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

UIKit中UIAction菜单使用Selector绑定动作报错的解决咨询

UIKit中UIAction绑定动作的正确实现方式

问题说明

在为UIKit菜单项配置UIAction时,第一个按钮无法绑定动作,报错Cannot find 'action' in scope;尝试修改后又出现Function is unused错误,需要明确通过Selector绑定动作的正确实现方式。

原有代码问题分析

  1. 第一段代码中,第一个UIAction的闭包写法错误:直接在闭包内写action: #selector(...)属于语法错误,闭包的作用是执行代码逻辑,而非声明参数。
  2. 第二段尝试的代码中,调用方法时写成self.RightSideBarButtonItemTapped(_:)只是引用了方法本身,没有进行实际调用,导致编译器提示“函数未被使用”。

正确实现方式

方式一:直接在UIAction闭包中调用@objc方法(推荐)

这是iOS14+ UIAction的标准用法,无需额外使用Selector,直接在闭包内执行目标方法:

class MessageViewController : UIViewController, UITableViewDelegate {
    
    // 正确配置第一个UIAction
    private lazy var first = UIAction(title: "Edit", image: UIImage(systemName: "pencil.circle"), attributes: [], state: .off) { [weak self] _ in
        // 直接调用目标方法,传入合适的sender(可传nil或当前UIAction实例,根据方法定义调整)
        self?.RightSideBarButtonItemTapped(nil)
    }
    
    private lazy var second = UIAction(title: "Second", image: UIImage(systemName: "pencil.circle"), attributes: [.destructive], state: .on) { [weak self] _ in
        self?.sendMessageRightSideBarButtonItemTapped(nil)
    }
    
    private lazy var third = UIAction(title: "Third", image: UIImage(systemName: "pencil.circle"), attributes: [], state: .off) { _ in
        print("third")
    }
    
    private lazy var menu = UIMenu(title: "new", children: [first, second, third])
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        let rightBarButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: nil)
        if #available(iOS 14.0, *) {
            rightBarButton.menu = menu
        }
        navigationItem.rightBarButtonItem = rightBarButton
    }
    
    // 确保方法标记为@objc,参数类型与调用时传入值匹配
    @objc func RightSideBarButtonItemTapped(_ sender: UIBarButtonItem?) {
        let vc = IceWorldView()
        present(vc, animated: true)
    }
    
    @objc func sendMessageRightSideBarButtonItemTapped(_ sender: UIBarButtonItem?) {
        print("Second action triggered")
    }
}

方式二:通过Selector绑定(兼容旧习惯)

如果坚持使用Selector,可在闭包内通过perform(_:with:)执行目标方法:

private lazy var first = UIAction(title: "Edit", image: UIImage(systemName: "pencil.circle"), attributes: [], state: .off) { [weak self] action in
    // 使用perform配合Selector执行方法
    self?.perform(#selector(self?.RightSideBarButtonItemTapped(_:)), with: action)
}

关键注意事项

  • 闭包内使用[weak self]避免循环引用,防止内存泄漏。
  • @objc标记的方法参数类型要和调用时传入的参数匹配。
  • 不要在闭包内仅写#selector(...),这只是一个选择器常量,不会触发方法执行。

内容的提问来源于stack exchange,提问作者Mai pa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:01:13