以编程方式在 UIButton 上设置目标/操作?

Posted

技术标签:

【中文标题】以编程方式在 UIButton 上设置目标/操作?【英文标题】:Setting target/action on UIButton programmatically? 【发布时间】:2016-10-02 18:44:36 【问题描述】:

在我的应用程序中,我的流程类似于:用户按下一个按钮,该按钮会更改 UIBarButtonItems,当用户单击其中一个按钮时,它会更改为其他内容。但是,单击其中一个时出现以下异常。

  *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[App.MapViewController revealLeftView]: unrecognized selector sent to instance 0x7fbc90c404c0'

首先,故事板中添加的按钮的动作设置如下:

menuButton.action = #selector(PBRevealViewController.revealLeftView)
toolboxMenuButton.action = #selector(PBRevealViewController.revealRightView)

当用户点击屏幕上其他地方的按钮时,我会像这样更改 UIBarButtons:

let leftButton: UIButton = UIButton(type: UIButtonType.custom)
//set image for button
leftButton.setImage(UIImage(named: "close"), for: UIControlState.normal)
//add function for button
leftButton.addTarget(self, action: #selector(MapViewController.cancelAddFields), for: UIControlEvents.touchUpInside)
//set frame
leftButton.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
let leftBarButton = UIBarButtonItem(customView: leftButton)

let rightButton: UIButton = UIButton(type: UIButtonType.custom)
//set image for button
rightButton.setImage(UIImage(named: "add"), for: UIControlState.normal)
//add function for button
rightButton.addTarget(self, action: #selector(MapViewController.confirmCreateFields(sender:)), for: UIControlEvents.touchUpInside)
//set frame
rightButton.frame = CGRect(x: 0, y: 0, width: 24, height: 20)
let rightBarButton = UIBarButtonItem(customView: rightButton)

//assign button to navigationbar
self.navigationItem.rightBarButtonItem = rightBarButton
self.navigationItem.leftBarButtonItem = leftBarButton

这可以正常工作,当用户单击关闭按钮时,我会像这样更改 UIBarButtonItems:

let leftButton: UIButton = UIButton(type: UIButtonType.custom)
        //set image for button
        leftButton.setImage(UIImage(named: "MenuIcon_1"), for: UIControlState.normal)
        //add function for button
        //leftButton.addTarget(self, action: #selector(MapViewController.cancelAddFields), for: UIControlEvents.touchUpInside)
        //set frame
        leftButton.frame = CGRect(x: 0, y: 0, width: 24, height: 24)

        let rightButton: UIButton = UIButton(type: UIButtonType.custom)
        //set image for button
        rightButton.setImage(UIImage(named: "ToolsIcon_1"), for: UIControlState.normal)
        //add function for button
        //rightButton.addTarget(self, action: #selector(MapViewController.cancelAddFields), for: UIControlEvents.touchUpInside)
        //set frame
        rightButton.frame = CGRect(x: 0, y: 0, width: 24, height: 24)

        leftButton.addTarget(self, action: #selector(PBRevealViewController.revealLeftView), for: UIControlEvents.touchUpInside)
        rightButton.addTarget(self, action: #selector(PBRevealViewController.revealRightView), for: UIControlEvents.touchUpInside)

        let leftBarButton = UIBarButtonItem(customView: leftButton)
        let rightBarButton = UIBarButtonItem(customView: rightButton)
        //assign button to navigationbar
        self.navigationItem.rightBarButtonItem = rightBarButton
        self.navigationItem.leftBarButtonItem = leftBarButton

它显示一切都很好,但是当我单击其中一个时,它会引发上述异常。我究竟做错了什么?我已经尝试了 UIBarButtonItem 本身的 .action,似乎也不起作用。

【问题讨论】:

在该异常中,您可以看到它发生的确切行,向我们展示更多内容 我已经更新了问题例外。 您知道如果将target 设置为selfselector 也必须在self(当前类)中实现吗? 我想知道我的方法是否错误。在我的 ViewDidLoad 中,我设置了这些 menuButton.action = #selector(PBRevealViewController.revealLeftView)menuButton.target = self.revealViewController() 【参考方案1】:

似乎在:

leftButton.addTarget(self, action: #selector(PBRevealViewController.revealLeftView), for: UIControlEvents.touchUpInside)

self(目标)实际上不是PBRevealViewController 的实例,而是MapViewController。这意味着您正在告诉按钮在 MapViewController 上调用方法 revealLeftView

确保您使用的是正确的target

【讨论】:

以上是关于以编程方式在 UIButton 上设置目标/操作?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式创建的 UIButton 为目标

无法在 UITableViewCell 中以编程方式创建的 UIButton 上设置图像

以编程方式在UIButton上设置图像和文本

以编程方式在 ScrollView 中的 UIButton

在 IOS 中以编程方式设置动作侦听器

以编程方式填充 UIStackView