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、关于事件名称的管理目前我的做法是建立了一个单独的类文件来声明,如果各位同学有好的做法可以自由发挥

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,612评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,142评论 1 32
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AGI阅读 16,009评论 3 119
  • 就是如此的纠结。 最近想要解决自己入睡难的问题,我想自己真的是想的太多,没有什么是不能解决的,如果自己没...
    逢束阅读 284评论 0 0
  • 是风迷了眼 才让泪水绽放的如初夏的花 站在空旷的田野 只有那晚归的燕雀能听懂 我心里的话 还能否回到最初 像个孩子...
    普辞阅读 741评论 2 2