J_K_D 2017-10-05 15:53
关于用柯里化实现Target-Action的疑问
回复:0 查看:4114
在看了喵神的书籍后,一直有个疑问,就是里面说到的使用swift的柯里化来封装Target-Action模式。先上代码(
代码中稍微有改动,我将Control继承了UIButton):
然后查了原本出自的博客文,说是这样使用
然后我就发现,onButtonTap这个方法是没办法触发的,除非,我自己给button添加一个target-action,然后在自己绑定的Action里 面条用performActionForControlEvent方法。代码如下:
如果要这样使用,封装的意义在哪里,不是画蛇添足吗?求大神解答,谢谢。
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") } }
然后我就发现,onButtonTap这个方法是没办法触发的,除非,我自己给button添加一个target-action,然后在自己绑定的Action里 面条用performActionForControlEvent方法。代码如下:
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. } }
如果要这样使用,封装的意义在哪里,不是画蛇添足吗?求大神解答,谢谢。