protocol TargetAction { func performAction() } struct TargetActionWrapper<T: AnyObject> : TargetAction { weak var target: T? let action: (T) -> () -> () func performAction() -> () { if let t = target { action(t)() } } } enum ControlEvent { case TouchUpInside case ValueChanged // ... } class Control : UIButton{ var actions = [ControlEvent: TargetAction]() func setTarget<T: AnyObject>(target: T, action: @escaping (T) -> () -> (), controlEvent: ControlEvent) { actions[controlEvent] = TargetActionWrapper(target: target, action: action) } func removeTargetForControlEvent(controlEvent: ControlEvent) { actions[controlEvent] = nil } func performActionForControlEvent(controlEvent: ControlEvent) { actions[controlEvent]?.performAction() } }
class MyViewController { let button = Control() func viewDidLoad() { button.setTarget(target: self, action: MyViewController.onButtonTap, controlEvent: .TouchUpInside) } func onButtonTap() { print("Button was tapped") } }
class ViewController: UIViewController { let button = Control.init(frame: CGRect.init(x: 0, y: 0, width: 100, height: 40)) override func viewDidLoad() { super.viewDidLoad() button.center = self.view.center button.setTitle("anniu", for: .normal) button.backgroundColor = UIColor.blue self.view.addSubview(button) // Do any additional setup after loading the view, typically from a nib. button.setTarget(target: self, action: ViewController.onButtonTap, controlEvent: .TouchUpInside) button.addTarget(self, action: #selector(ViewController.action), for: .touchUpInside) } @objc func action(){ button.performActionForControlEvent(controlEvent: .TouchUpInside) } func onButtonTap() { print("Button click") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }