下面的代码可以正常编译,但会因unrecognized selector sent to instance
错误而崩溃。
我有一个类继承自UIViewController
:
class Controller: UIViewController {
override func viewDidLoad() {
let toolbarWrapper = CustomToolbarWrapper(view: view, target: self)
let toolbar = toolbarWrapper.toolbarView
view.addSubview(toolbar)
... Other code ...
}
}
另一个类只是 a 的包装器UIView
并包含按钮:
class CustomToolbarWrapper {
var toolbarView: UIView
init(view: UIView, target: Any) {
let height: CGFloat = 80
toolbarView = UIView(frame: CGRect(x: 0, y: view.frame.height - height, width: view.frame.width, height: height))
let button = UIButton()
... Some button layout code ...
button.addTarget(target, action: #selector(CustomToolbar.buttonTapped(_:)), for: .touchUpInside)
toolbarView.addSubview(button)
}
@objc static func buttonTapped(_ sender: Any) {
print("button tapped")
}
}
为了清楚起见,我省略了一大块代码,并保留了我认为必要的部分。我认为我的代码不起作用,因为我误解了目标在addTarget
函数中的工作方式。通常,我只是self
用作按钮操作的目标,所以我只是尝试self
从视图控制器传递给CustomToolbarWrapper
'sinit
函数。
我还尝试了什么:
将按钮的目标从更改target
为self
:
button.addTarget(self, action: #selector(CustomToolbar.buttonTapped(_:)), for: .touchUpInside)
导致应用程序不再崩溃。然而,相反,我相信这行代码没有做任何事情(由于某种原因不会引发错误?),因为尝试打印button.allTargets
甚至button.allTargets.count
导致应用程序在编译时崩溃,出现 EXC_BREAKPOINT 错误并且没有错误描述在控制台或 XCode UI 中(这让我更加困惑,因为我的代码中没有断点!)。
此外,制作buttonPressed(_:)
非静态不会改变前面提到的任何观察结果。
另外,为了确保按钮实际上可以交互,我在以下位置添加了viewDidLoad()
这个Controller
:
for subview in toolbar.subviews? {
if let button = subview as? UIButton {
button.addTarget(self, action: #selector(buttonPressed(_:)), for: .touchUpInside)
}
}
Controller
并为按钮添加了一个简单的测试方法:
@objc func buttonPressed(_ sender: UIButton) {
print("Button Pressed")
}
运行代码确实会在控制台日志中打印“Button Pressed”,因此用户应该能够与该按钮进行交互。
如果您认为这不足以解决问题,请随时告诉我,我将发布更多详细信息。
编辑
我更喜欢在类中保留按钮操作的实现,CustomToolbarWrapper
以防止将来重复代码,因为无论在哪里CustomToolbarWrapper
创建实例,操作都是相同的。