简体   繁体   English

正确通过选择器 Swift 5 iOS

[英]Passing Selector properly Swift 5 iOS

I am trying to pass a method to a view, getting an unrecognized selector exception.我试图将一个方法传递给一个视图,得到一个无法识别的选择器异常。

The first snippet is from my view controller and I'm passing the editSelector to a view that has a property Selector.I am getting this error when I tap the edit button:第一个片段来自我的视图 controller,我将 editSelector 传递给具有属性 Selector 的视图。当我点击编辑按钮时出现此错误:

-[CalorieTracker.TitleStackView editSelector:]: unrecognized selector sent to instance 0x7fe65e612800' -[CalorieTracker.TitleStackView editSelector:]:无法识别的选择器发送到实例 0x7fe65e612800'

I'm not sure why as it looks like I've defined it properly?我不知道为什么看起来我已经正确定义了它?

@objc private func editSelector(_ sender:UIButton!){
        print("Yeet")
    }

    lazy var titleStackView: TitleStackView = {
        let titleStackView = TitleStackView(frame: CGRect(origin: .zero, size: CGSize(width: view.bounds.width, height: 44.0)), editSelector: #selector(self.editSelector(_:)))
        titleStackView.translatesAutoresizingMaskIntoConstraints = false
        return titleStackView
    }()



class TitleStackView: UIStackView {

    init(frame: CGRect, editSelector: Selector) {
        super.init(frame:frame)
        self.editSelector = editSelector
        commonInit()
    }

    var editSelector:Selector?


    required init(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    private func commonInit() {
        axis = .horizontal
        alignment = .center
        addArrangedSubview(titleLabel)
        addArrangedSubview(button)
    }

    lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: UIFont.preferredFont(forTextStyle: .largeTitle).pointSize, weight: .heavy)
        label.text = "My Foods"
        label.setContentHuggingPriority(.defaultLow, for: .horizontal)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    lazy var button: UIButton = {
        let buttonWidth: CGFloat = 35.0
        let button = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: buttonWidth, height: buttonWidth)))
        button.setTitleColor(.systemBlue, for: .normal)
        button.setTitle("Edit", for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
        button.heightAnchor.constraint(equalToConstant: buttonWidth).isActive = true
        button.layer.masksToBounds = true
        button.isUserInteractionEnabled = true
        button.addTarget(self, action: self.editSelector!, for: .touchUpInside)
        return button
    }()
}

As you set the target as the class当您将目标设置为 class

button.addTarget(self, action: self.editSelector!, for: .touchUpInside)

which doesn't contain the selector, btw you should only pass a delegate and call a method inside the target class它不包含选择器,顺便说一句,您应该只传递一个委托并调用目标 class 内的方法

weak var delegate:VCName?

init(frame: CGRect, delegate: Any) {
   super.init(frame:frame)
   self.delegate = delegate

then然后

button.addTarget(delegate!, action: self.editSelector!, for: .touchUpInside)

and add the selector impkenetation inside the calling class并在调用 class 中添加选择器 impkenetation

Seems you are only passing the selector.似乎你只是通过选择器。 You would also need to pass the target which is the view controller and not the view.您还需要传递目标,即视图 controller 而不是视图。

init(frame: CGRect, target: Any, editSelector: Selector) {
    super.init(frame:frame)
    self.target = target
    self.editSelector = editSelector
    commonInit()
}

var target:Any?
var editSelector:Selector?

And modify initialization as follows:并修改初始化如下:

lazy var titleStackView: TitleStackView = {
    let titleStackView = TitleStackView(frame: CGRect(origin: .zero, size: CGSize(width: view.bounds.width, height: 44.0)), target: self, editSelector: #selector(self.editSelector(_:)))
    titleStackView.translatesAutoresizingMaskIntoConstraints = false
    return titleStackView
}()

I have got a better approach than the above, remove the custom init method and use below code:我有比上面更好的方法,删除自定义 init 方法并使用以下代码:

lazy var titleStackView: TitleStackView = {
    let titleStackView = TitleStackView(frame: CGRect(origin: .zero, size: CGSize(width: view.bounds.width, height: 44.0)))
    titleStackView.button.addTarget(self, action: #selector(self.editSelector(_:)), for: .touchUpInside)
    titleStackView.translatesAutoresizingMaskIntoConstraints = false
    return titleStackView
}()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM