J_K_D 2017-10-05 15:53
关于用柯里化实现Target-Action的疑问
回复:0 查看:4458
在看了喵神的书籍后,一直有个疑问,就是里面说到的使用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.
}
} 如果要这样使用,封装的意义在哪里,不是画蛇添足吗?求大神解答,谢谢。