You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:24:06