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

Swift4中如何不使用Objective-C为Label添加点击事件

问题描述

我目前有一段Objective-C风格的代码,用于给Label(hashTag.hashTag1)添加点击事件,触发后通过通知中心跳转到其他页面并传递数据。代码可以正常运行,但我希望完全移除Objective-C及NS相关函数,改为纯Swift 4实现。

现有代码

Objective-C风格的处理函数

@objc func handleTapHash(gestureRecognizer: UIGestureRecognizer) { 
    NotificationCenter.default.post(name: NSNotification.Name("ViewerOfHash"), object: nil) 
} 

@objc func ViewerOfHash() { 
    performSegue(withIdentifier: "ViewerOfHash", sender: nil) 
    PassDataController.addData(newData: "12300") 
    MainVC.tof = 1 
} 

给Label添加点击事件的代码

let gestureRecognizer1 = UITapGestureRecognizer(target: self, action: #selector(self.handleTapHash)) 
hashTag.hashTag1.addGestureRecognizer(gestureRecognizer1) 

需求

完全不使用Objective-C及NS相关函数,通过Label点击向另一个页面传递数据,改为纯Swift 4实现。


纯Swift 4实现方案

我给你整理了两种纯Swift的改造思路,第二种更简洁直接,推荐优先使用:

方案一:保留通知逻辑,替换OC相关写法

如果想保留原有的通知中转逻辑,我们可以从这几个点改造:

  1. 用Swift闭包替代@objc手势方法
    给UITapGestureRecognizer写个小扩展,让它支持闭包回调,彻底摆脱@objc标记:

    extension UITapGestureRecognizer {
        convenience init(tapHandler: @escaping (UITapGestureRecognizer) -> Void) {
            self.init()
            self.addTarget(self, action: #selector(handleTap(_:)))
            self.tapHandler = tapHandler
        }
        
        private struct AssociatedKeys {
            static var tapHandler = "tapHandler"
        }
        
        private var tapHandler: ((UITapGestureRecognizer) -> Void)? {
            get {
                return objc_getAssociatedObject(self, &AssociatedKeys.tapHandler) as? ((UITapGestureRecognizer) -> Void)
            }
            set {
                objc_setAssociatedObject(self, &AssociatedKeys.tapHandler, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
        
        @objc private func handleTap(_ gesture: UITapGestureRecognizer) {
            tapHandler?(gesture)
        }
    }
    

    注:这里的objc_getAssociatedObject是Swift关联对象的标准用法,不属于业务层面的OC依赖,是实现闭包回调的必要手段。

  2. 用Swift风格的通知名称
    替换原有的字符串字面量通知名,用类型安全的静态属性定义:

    extension Notification.Name {
        static let viewerOfHash = Notification.Name("ViewerOfHash")
    }
    
  3. 移除@objc的通知处理方法
    用Swift的闭包式观察者替代@objc方法:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 添加通知观察者
        NotificationCenter.default.addObserver(forName: .viewerOfHash, object: nil, queue: .main) { [weak self] _ in
            guard let self = self else { return }
            self.performSegue(withIdentifier: "ViewerOfHash", sender: nil)
            PassDataController.addData(newData: "12300")
            MainVC.tof = 1
        }
        
        // 给Label添加点击手势
        let gestureRecognizer1 = UITapGestureRecognizer { [weak self] _ in
            guard let self = self else { return }
            NotificationCenter.default.post(name: .viewerOfHash, object: nil)
        }
        hashTag.hashTag1.isUserInteractionEnabled = true // 必须开启Label交互!
        hashTag.hashTag1.addGestureRecognizer(gestureRecognizer1)
    }
    

方案二:直接跳转(更简洁推荐)

其实点击Label后直接跳转页面完全不需要通知中转,这种方式代码更简洁,也完全是纯Swift实现:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 给Label添加点击手势,直接处理跳转和传参
    let gestureRecognizer1 = UITapGestureRecognizer { [weak self] _ in
        guard let self = self else { return }
        // 把要传递的数据作为sender传入segue
        self.performSegue(withIdentifier: "ViewerOfHash", sender: "12300")
        MainVC.tof = 1
    }
    hashTag.hashTag1.isUserInteractionEnabled = true
    hashTag.hashTag1.addGestureRecognizer(gestureRecognizer1)
}

// 在segue准备阶段传递数据到目标页面
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ViewerOfHash", let data = sender as? String {
        PassDataController.addData(newData: data)
        // 更推荐的方式是直接给目标VC的属性赋值,比如:
        // if let targetVC = segue.destination as? TargetViewController {
        //     targetVC.receivedData = data
        // }
    }
}

关键注意点

  • 一定要给Label设置isUserInteractionEnabled = true,否则点击手势不会生效。
  • 使用[weak self]避免循环引用,这是Swift内存管理的最佳实践。

内容的提问来源于stack exchange,提问作者Soonmyun Jang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:41:41