1

我创建了一个自定义控件,我想在@IBInspectable 属性中传递操作,以实现与使用UIButton 设置@IBAction 相同的效果。我该怎么做呢?

class MyControl: UIButton {
  // Problem with this string approach is 
  //I have no way to know which instance to perform the selector on.
  @IBInspectable var tapAction: String?  

  // set up tap gesture
  ...

  func labelPressed(_ sender: UIGestureRecognizer) {
    if let tapAction = tapAction {
      // How should I convert the string in tapAction into a selector here? 
      //I also want to pass an argument to this selector.
    }
  }
}
4

1 回答 1

0

我真的不知道你为什么想要它,但是......这是我的解决方案:

创建一个MyActions类,其中包含MyControl可以调用的操作:

class MyActions: NSObject {
    func foo() {
        print("foo")
    }

    func bar() {
        print("bar")
    }

    func baz() {
        print("baz")
    }
}

将您的MyControl课程替换为

class MyControl: UIButton {

    @IBInspectable var actionClass: String?
    @IBInspectable var tapAction: String?
    private var actions: NSObject?

    override func awakeFromNib() {
        // initialize actions class
        let bundleName = Bundle.main.bundleIdentifier!.components(separatedBy: ".").last!
        let className = "\(bundleName).\(actionClass!)"

        guard let targetClass = NSClassFromString(className) as? NSObject.Type else {
            print("Class \(className) not found!")
            return
        }

        self.actions = targetClass.init()

        // create tap gesture
        let tap = UITapGestureRecognizer(target: self, action: #selector(pressed(_:)))
        self.addGestureRecognizer(tap)
    }

    func pressed(_ sender: UIGestureRecognizer) {
        actions!.perform(Selector(tapAction!))
    }
}

并且,设置按钮的属性:

您可以在运行时更改 Tap Action,例如:

@IBAction func buttonChangeAction(_ sender: Any) {

    buttonMyControl.tapAction = textField.text!
}

也许您可以更改我的代码以传递参数,但是……这是您想要的吗?

于 2017-05-15T02:36:21.860 回答