越來(lái)越多的App呈現(xiàn)出復(fù)雜的UI樣式,導(dǎo)致視圖層級(jí)過(guò)多;而在swift中,多數(shù)人的做法都是選擇盡量嚴(yán)謹(jǐn)?shù)目刂圃L問(wèn)權(quán)限踢代,更多的private 和 fileprivate 被用來(lái)修飾屬性和方法,這種情況下嗅骄,一旦需要跨越多個(gè)層次進(jìn)行事件傳遞就變得較為繁瑣胳挎,受響應(yīng)鏈原理的啟發(fā),之前在OC語(yǔ)言的環(huán)境中建立了一套剔除這部分功能耦合度的工具溺森,現(xiàn)在將其翻譯成Swift版本慕爬,直接上代碼~~~
建立 UIResponder 的 擴(kuò)展
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、事件發(fā)起者調(diào)用 self.next?.transitionInfo(info:AnyObject)方法
2儿惫、最終響應(yīng)的Responder遵循TS_UserInteraction_DataTransition并實(shí)現(xiàn)協(xié)議方法 ts_userInteraction(info:AnyObject)
場(chǎng)景1 imageView 點(diǎn)擊, AViewControllerzh中跳轉(zhuǎn)個(gè)人信息頁(yè)面
步驟1澡罚,ImageView點(diǎn)擊事件開始發(fā)起響應(yīng)鏈?zhǔn)录鬟f
@objc func imageClick(sender:UITapGestureRecognizer) {
self.next?.ts_transitionInfo(info: ((sender.view?.tag)! - 100) as AnyObject)
}
步驟2,AViewController實(shí)現(xiàn)ts_userInteraction方法肾请,終止本次響應(yīng)鏈?zhǔn)录鬟f
extension AViewController:TS_UserInteraction_DataTransition {
func ts_userInteraction(info: AnyObject) {
//處理push/present邏輯
}
}
場(chǎng)景2 cell 上的 imageView 點(diǎn)擊, cell攔截一次,向傳遞過(guò)程中已有的參數(shù)添加一個(gè)參數(shù) AViewControllerzh中跳轉(zhuǎn)個(gè)人信息頁(yè)面
場(chǎng)景1 imageView 點(diǎn)擊, AViewControllerzh中跳轉(zhuǎn)個(gè)人信息頁(yè)面
//圖片點(diǎn)擊更胖,利用響應(yīng)鏈逆向事件傳遞铛铁,封入圖片尺寸參數(shù)
@objc func imageClick(sender:UITapGestureRecognizer) {
self.next?.ts_transitionInfo(info: self.next?.transitionInfo(info: ["imageSize":"20*20"] as AnyObject)
}
步驟2隔显,Cell攔截一次,向已有參數(shù)內(nèi)增加一個(gè)userID參數(shù)饵逐,繼續(xù)本次響應(yīng)鏈?zhǔn)录鬟f
//Cell攔截一次括眠,向已有參數(shù)內(nèi)增加一個(gè)userID參數(shù)
extension ListTableViewCell:TS_UserInteraction_DataTransition {
func ts_userInteraction(info: AnyObject) {
//重新封裝參數(shù)
var dic : [String:String]? = info as? [String:String]
dic!["userID"] = "10002"
//繼續(xù)事件傳遞
self.next?.transitionInfo(info: dic as AnyObject)
}
}
步驟3,AViewController實(shí)現(xiàn)ts_userInteraction方法倍权,終止本次響應(yīng)鏈?zhǔn)录鬟f
extension AViewController:TS_UserInteraction_DataTransition {
func ts_userInteraction(info: AnyObject) {
//處理push/present邏輯
}
}
總結(jié):
1掷豺、非父、子控件間無(wú)法做到直接的事件傳遞
2薄声、關(guān)于事件名稱的管理目前我的做法是建立了一個(gè)單獨(dú)的類文件來(lái)聲明当船,如果各位同學(xué)有好的做法可以自由發(fā)揮