Swift中为多个UILabel添加滑动手势功能的实现方法
解决多个UILabel滑动修改数值的复用问题
嘿,作为Swift新手能实现单个Label的滑动功能已经很棒啦!现在要让多个统计类Label都拥有这个功能,核心思路是把“Label-数值”的对应关系通用化,不要把逻辑绑死在单个Label和变量上。我给你整理了修改方案,一步步来:
第一步:用字典存储每个Label的数值
原来的单个counter变量只能对应counterLabel,换成字典后可以同时记录多个Label的数值,每个Label都有自己独立的计数:
var labelCounters: [UILabel: Int] = [:]
第二步:给所有需要的Label统一添加手势
在viewDidLoad里,不要只给counterLabel加手势,而是把所有需要支持滑动的Label(比如counterLabel、kickLabel)放到一个数组里遍历,统一配置手势和初始化数值:
override func viewDidLoad() { super.viewDidLoad() // 把所有需要支持滑动的统计Label放到这里,后续加新Label直接加进数组就行 let targetLabels: [UILabel] = [counterLabel, kickLabel] let directions: [UISwipeGestureRecognizer.Direction] = [.up, .down, .left, .right] for label in targetLabels { // 初始化每个Label的初始数值为0,同时设置默认文本 labelCounters[label] = 0 label.text = "0" label.isUserInteractionEnabled = true // 给每个Label添加四个方向的滑动手势 for direction in directions { let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeGesture(_:))) swipeGesture.direction = direction label.addGestureRecognizer(swipeGesture) } } }
第三步:编写通用的滑动处理方法
把原来绑定死counterLabel的方法改成通用逻辑,通过sender.view拿到触发滑动的Label,再操作对应字典里的数值:
@objc func handleSwipeGesture(_ sender: UISwipeGestureRecognizer) { // 安全校验:确保触发手势的是UILabel,且字典里有对应的计数 guard let targetLabel = sender.view as? UILabel, var currentCount = labelCounters[targetLabel] else { return } UIView.animate(withDuration: 1.0) { switch sender.direction { case .right: print("Swiped Right on \(targetLabel.text ?? "unknown label")") currentCount += 1 case .left: print("Swiped Left on \(targetLabel.text ?? "unknown label")") currentCount -= 1 case .up: print("Swiped Up on \(targetLabel.text ?? "unknown label")") currentCount += 5 case .down: print("Swiped Down on \(targetLabel.text ?? "unknown label")") currentCount = 0 default: break } // 更新字典里的数值和Label显示文本 self.labelCounters[targetLabel] = currentCount targetLabel.text = String(currentCount) } }
完整修改后的代码
import UIKit class ViewController: UIViewController { @IBOutlet weak var counterLabel: UILabel! @IBOutlet weak var kickLabel: UILabel! // 用字典存储每个Label对应的独立计数 var labelCounters: [UILabel: Int] = [:] override func viewDidLoad() { super.viewDidLoad() // 统一处理需要支持滑动的统计Label let targetLabels: [UILabel] = [counterLabel, kickLabel] let directions: [UISwipeGestureRecognizer.Direction] = [.up, .down, .left, .right] for label in targetLabels { labelCounters[label] = 0 label.text = "0" label.isUserInteractionEnabled = true for direction in directions { let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeGesture(_:))) swipeGesture.direction = direction label.addGestureRecognizer(swipeGesture) } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } @objc func handleSwipeGesture(_ sender: UISwipeGestureRecognizer) { guard let targetLabel = sender.view as? UILabel, var currentCount = labelCounters[targetLabel] else { return } UIView.animate(withDuration: 1.0) { switch sender.direction { case .right: print("Swiped Right on \(targetLabel)") currentCount += 1 case .left: print("Swiped Left on \(targetLabel)") currentCount -= 1 case .up: print("Swiped Up on \(targetLabel)") currentCount += 5 case .down: print("Swiped Down on \(targetLabel)") currentCount = 0 default: break } self.labelCounters[targetLabel] = currentCount targetLabel.text = String(currentCount) } } }
额外小提示
- 以后如果要加新的统计Label(比如
punchLabel),只要把它加到targetLabels数组里就行,完全不用改其他逻辑 - 代码里的
guard let做了安全校验,避免因为手势绑定到非Label视图导致崩溃 - 保留了你原来的动画效果和打印日志,还新增了区分哪个Label被滑动的日志,方便调试
内容的提问来源于stack exchange,提问作者James Vanderhaak
相关产品推荐
相关产品推荐

