ios - 未调用编程式 UIButton 操作

标签 ios swift uibutton

我已经创建了一个类来创建/管理多个按钮和标签,并将它们添加到 View 中,但我无法从按钮中触发操作。

这是一个没有“MakerClass”的代码的简单版本,可以正常工作(代码在主 ViewController 中):

@objc func pressed(_ sender: UIButton!) {
    print("pressed")
}
    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    let backgroundButton = UIButton()
    backgroundButton.backgroundColor = UIColor.green
    backgroundButton.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    self.view.addSubview(backgroundButton)

    backgroundButton.addTarget(self, action: #selector(pressed(_:)), for: .touchUpInside)

}

这是我将按钮的创建放入不同类的版本

View Controller

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    MakerClass(intoView: self.view)                
}

创客类

class MakerClass {


    var backgroundButton: UIButton = UIButton()


    @objc func iwastouched(_ sender: UIButton!) {
        print("touched")
    }

    init(intoView: UIView){

        backgroundButton.backgroundColor = UIColor.red
        backgroundButton.frame = CGRect(x: 0, y: 200, width: 100, height: 100)
        intoView.addSubview(backgroundButton)
        backgroundButton.addTarget(self, action: #selector(iwastouched(_:)), for: .touchUpInside)

    }


}

我一直用来玩这个的项目可以从here下载。

我可能会以错误的方式解决这个问题,因为我是 iOS 编程的新手

最佳答案

问题是因为您没有保留 MakerClass,按钮的目标设置为 NSNull()

你可以通过添加...看到这个

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    let buttons = view.subviews as! [UIButton]
    for button in buttons {

        print(button)
        print("Target :", button.allTargets.first!)
    }
}
<UIButton: 0x7ff89fd04110; frame = (0 0; 100 100); opaque = NO; layer = <CALayer: 0x60000257bac0>>
Target : <TestProgrammaticButton.ViewController: 0x7ff89ff08050>
<UIButton: 0x7ff89fd05020; frame = (0 200; 100 100); opaque = NO; layer = <CALayer: 0x60000257bb40>>
Target : <null>

如果你想让按钮在你的 View Controller 中触发一个 Action 方法,你可以这样做......

class MakerClass {
    init(intoView: UIView, with viewController: ViewController) {
        // configure
        backgroundButton.addTarget(viewController, action: #selector(iwastouched(_:)), for: .touchUpInside)
    }
}

但这会将您的 MakerClass 与特定的 ViewController 类联系起来。

相反,您的 MakerClass 可以返回格式化的按钮,然后在 View Controller 中设置目标/操作。


更新

根据下面@RakeshaShastri 的评论,当目标设置为 NSNull() 时,应用程序将在响应链上寻找 UIResponder(通常是 UIViewUIViewController) 具有正确的函数签名。您案例中的响应者链是……

backgroundButton -> ViewController.view -> ViewController -> UIWindow

您也可以通过添加

来测试这一点
@objc func iwastouched(_ sender: UIButton!) {
    print("touched")
}

到您的 ViewController 类。

关于ios - 未调用编程式 UIButton 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52001842/

相关文章:

ios - 多个持久存储协调器核心数据

ios appid '' 不支持修改 'Maps'功能

ios - UIButton action(rx.tap) 用 RxSwift 响应不同的 PublishSubjects

ios - 如何从 IOS 的启动屏幕检查 NsUserDefaults?

swift - CIDetector 是否适用于其他条码类型

ios - Swift 3 和 backendless - 我如何上传图片?

ios - 应为 ',' 分隔符和未解析的标识符

iphone - 在主视图 Controller 的自定义单元格内使用来自 UIButton 的 IBAction

CSS Roll Over with Sprites & 滑动门

c# - 单点触控 : UIDocumentInteractionController preview right bar button not working in iPhone