我创建了一个动态UIButton,我想动态地将监听器设置为按钮。但我得到错误:
使用未解析的标识符' myFuncName(发件人:)'
我的代码(您可以将其粘贴到Xcode中并运行):
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// add my button
let button = Btn()
button.setListener(buttonTapped)
view.addSubview(button)
}
@objc func buttonTapped() {
print("tapped")
}
}
// -------------------------------
class Btn: UIControl {
fileprivate let button: UIButton = {
let swapButton = UIButton()
let size = CGFloat(50)
swapButton.frame.size = CGSize(width: size, height: size)
swapButton.backgroundColor = UIColor.green
return swapButton
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(button)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
addSubview(button)
}
func setListener(_ listener: @escaping () -> Void) {
// Error - Use of unresolved identifier 'listener(sender:)'
button.addTarget(self, action: #selector(listener(sender:)), for: .touchUpInside)
}
}
答案 0 :(得分:2)
#selector
创建一个指向函数的Selector
。如果要调用自定义侦听器代码块,则需要将其分配给Btn
的实例var,然后从私有函数调用它。
let button = Btn()
button.listener = {
// your closure here
}
class Btn: UIControl {
weak var listener: (() -> Void)?
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(button)
button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
}
@objc private func buttonTapped(_ sender: UIButton) {
self.listener?()
}
}
答案 1 :(得分:1)
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// add my button
let button = Btn()
self.addListener(to: button, using: #selector(buttonTapped))
view.addSubview(button)
}
@objc func buttonTapped() {
print("tapped")
}
func addListener(to button: UIButton, using handler: Selector) {
button.addTarget(self, action: handler, for: .touchUpInside)
}
}
以上代码是我相信你想要实现的。 addTarget
方法的要点是告诉控件哪个类(目标;本例中为self
),方法(操作)以及何时调用方法(.touchUpInside
)。在这里,我们说我想在buttonTapped
收到ViewController
事件时在button
班级中调用.touchUpInside
方法。
答案 2 :(得分:1)
嗯,我认为这种方法有问题。 UIButton是UIControl的子类,你正试图做一些不合法的事情。简而言之,您正在父类本身中创建子类的对象。
解决方案:在我看来,你可能想要UIButton的子类而不是UIControl。例如。
class CustomButton:UIButton {
// Properties
var closure: () -> Void = {
/// empty initialization
}
override func awakeFromNib() {
super.awakeFromNib()
self.addTarget(self, action: #selector(self.buttonTapped), for: .touchUpInside)
}
// methods and selectors
@objc func buttonTapped() {
// Your Code.
self.closure()
}
}
类VC:UIViewController {
//自定义按钮的插座。 @IBOutlet弱变量按钮:CustomButton!
override func viewDidLoad() {
super.viewDidLoad()
button.closure = self.buttonTapped
}
public func buttonTapped(){
print("Code Works...")
}
}
说明: 1.在上面的代码中,我们对UIButton进行了分类,并在其中声明了一个属性。这是一种返回void的函数。
然后我们将目标添加到UIButton子类的函数中。每次点击按钮时,都会执行“按钮点按”功能。
然后我们直接将函数分配给属性“closure”。 ('var closure'是返回void的函数类型的属性。)
希望这会有所帮助。 :)