Swift 利用响应链进行事件逆向传递

越来越多的App呈现出复杂的UI样式,导致视图层级过多;而在swift中,多数人的做法都是选择尽量严谨的控制访问权限,更多的private 和 fileprivate 被用来修饰属性和方法,这种情况下,一旦需要跨越多个层次进行事件传递就变得较为繁琐,受响应链原理的启发,之前在OC语言的环境中建立了一套剔除这部分功能耦合度的工具,现在将其翻译成Swift版本,直接上代码~~~

建立 UIResponder 的 扩展


import Foundation
import UIKit
@objc public protocol TS_UserInteraction_DataTransition {
    @objc func ts_userInteraction(info:AnyObject)
}
public extension UIResponder{
    func ts_transitionInfo(info:AnyObject?) {
        if self.conforms(to: TS_UserInteraction_DataTransition.self) {
            (self as! TS_UserInteraction_DataTransition).ts_userInteraction(info:info!)
        }else{
            self.next?.ts_transitionInfo(info:info!)
        }
    }
}

使用

1、事件发起者调用 self.next?.transitionInfo(info:AnyObject)方法

2、最终响应的Responder遵循TS_UserInteraction_DataTransition并实现协议方法 ts_userInteraction(info:AnyObject)

场景1 imageView 点击, AViewControllerzh中跳转个人信息页面

步骤1,ImageView点击事件开始发起响应链事件传递

    @objc func imageClick(sender:UITapGestureRecognizer) {
        self.next?.ts_transitionInfo(info: ((sender.view?.tag)! - 100) as AnyObject)
    }

步骤2,AViewController实现ts_userInteraction方法,终止本次响应链事件传递

   extension AViewController:TS_UserInteraction_DataTransition {
    func ts_userInteraction(info: AnyObject) {
        //处理push/present逻辑
    }
}

场景2 cell 上的 imageView 点击, cell拦截一次,向传递过程中已有的参数添加一个参数 AViewControllerzh中跳转个人信息页面

场景1 imageView 点击, AViewControllerzh中跳转个人信息页面

//图片点击,利用响应链逆向事件传递,封入图片尺寸参数
@objc func imageClick(sender:UITapGestureRecognizer) {
            self.next?.ts_transitionInfo(info: self.next?.transitionInfo(info: ["imageSize":"20*20"] as AnyObject)
        }

步骤2,Cell拦截一次,向已有参数内增加一个userID参数,继续本次响应链事件传递

 //Cell拦截一次,向已有参数内增加一个userID参数
extension ListTableViewCell:TS_UserInteraction_DataTransition {
    func ts_userInteraction(info: AnyObject) {
       //重新封装参数
        var dic : [String:String]? = info as? [String:String]
        dic!["userID"] = "10002"
        //继续事件传递
        self.next?.transitionInfo(info: dic as AnyObject)
    }
}

步骤3,AViewController实现ts_userInteraction方法,终止本次响应链事件传递

   extension AViewController:TS_UserInteraction_DataTransition {
    func ts_userInteraction(info: AnyObject) {
        //处理push/present逻辑
    }
}

总结:
1、非父、子控件间无法做到直接的事件传递
2、关于事件名称的管理目前我的做法是建立了一个单独的类文件来声明,如果各位同学有好的做法可以自由发挥

你可能感兴趣的:(Swift 利用响应链进行事件逆向传递)