正确传递选择器 Swift 5 iOS

Passing Selector properly Swift 5 iOS

我试图将一个方法传递给一个视图,得到一个无法识别的选择器异常。

第一个片段来自我的视图控制器,我将 editSelector 传递给具有 属性 Selector.I 的视图,当我点击编辑按钮时出现此错误:

-[CalorieTracker.TitleStackView editSelector:]: unrecognized selector sent to instance 0x7fe65e612800'

我不确定为什么我似乎已经正确定义了它?

@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
    }()
}

当您将目标设置为 class

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

它不包含选择器,顺便说一句,你应该只传递一个委托并在目标内部调用一个方法 class

weak var delegate:VCName?

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

然后

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

并在调用中添加选择器 impkenetation class

看来您只是通过了选择器。您还需要传递目标,即视图控制器而不是视图。

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

var target:Any?
var editSelector:Selector?

并修改初始化如下:

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
}()

我有一个比上面更好的方法,删除自定义初始化方法并使用下面的代码:

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
}()