本人有若干成套學(xué)習(xí)視頻, 可試看! 可試看! 可試看, 重要的事情說三遍 包含Java
, 數(shù)據(jù)結(jié)構(gòu)與算法
, iOS
, 安卓
, python
, flutter
等等, 如有需要, 聯(lián)系微信tsaievan
.
現(xiàn)在有一個需求, 如果一個自定義cell中有一個button, button的點(diǎn)擊事件要將自定義cell中的某個屬性值傳給控制器, 應(yīng)該怎么做?
當(dāng)然你可以利用代理, 通知, 和block回調(diào), 除此之外, 還有沒有其他辦法呢? 有! 那就是今天要說的路由響應(yīng)鏈方法.
說到路由響應(yīng)鏈, 其實(shí)跟路由器的路由半毛錢關(guān)系沒有. 關(guān)鍵在于響應(yīng)鏈, 說到響應(yīng)鏈, 就不得不說一下UIResponder
The UIResponder class defines an interface for objects that respond to and handle events. It is the superclass of UIApplication, UIView and its subclasses (which include UIWindow). Instances of these classes are sometimes referred to as responder objects or, simply, responders.
UIResponder類定義了一個對象接口用來響應(yīng)和處理事件, 它是UIApplication, UIView以及UIView的子類(包括UIWindow)的父類, 這些類的實(shí)例對象被稱為響應(yīng)對象或者響應(yīng)者
然后UIResponder對象有一個重要的屬性叫做nextResponder, 下一個響應(yīng)者. 現(xiàn)在回到我們的需求
當(dāng)button向controller傳值的時候(紅色虛線箭頭方向), 這是逆?zhèn)? 大部分情況下我們都使用通知代理和block, 但是nextResponsder這個屬性讓我們可以直接獲取到控件的父類
- 首先,我為UIResponder建立一個分類
- 在分類中, 我實(shí)現(xiàn)這樣一個方法
#import "UIResponder+Router.h"
@implementation UIResponder (Router)
- (void)routerWithEventName:(NSString *)eventName userInfo:(NSDictionary *)userInfo {
if (self.nextResponder) {
[[self nextResponder] routerWithEventName:eventName userInfo:userInfo];
}
}
@end
第一個參數(shù)是事件名稱, 第二個參數(shù)是需要傳遞的參數(shù)信息
看起來這樣一個方法會陷入死循環(huán), 其實(shí)不然, 當(dāng)self.nextResponder向上一直找到UIApplication都還不能響應(yīng)事件的時候, 系統(tǒng)就會自動丟棄這個事件
而當(dāng)我控制器中重寫這個方法的時候, 相當(dāng)于重寫父類方法的時候,那么系統(tǒng)就會走子類的方法, 那么參數(shù)就直接傳遞給控制器了
控制器中重寫父類方法
- (void)routerWithEventName:(NSString *)eventName userInfo:(NSDictionary *)userInfo {
if ([eventName isEqualToString:YFTransferNameEvent]) {
NSString * name = userInfo[YFUserName];
NSLog(@"用戶的姓名為:%@",name);
}
}
cell中Button的點(diǎn)擊事件
- (void)buttonClickAction:(UIButton *)sender {
[sender routerWithEventName:YFTransferNameEvent userInfo:@{
YFUserName:[self userName],
}];
}
也就是說, button將事件處理傳遞給nextResponder, 也就是cell, cell沒有重寫父類方法, 繼續(xù)將事件傳遞給tableView, tableView也沒有重寫父類方法, 于是將事件處理傳遞給控制器的view,控制器的view也沒有重寫父類方法, 于是將事件處理傳遞給控制器, 控制器重寫了父類方法, 于是就走控制器重寫的方法, 進(jìn)行事件處理, 事件就成功地從button傳到了控制器.
實(shí)現(xiàn)效果如下圖, 我依次點(diǎn)擊每一個button,(注意:不是點(diǎn)擊cell),就會在控制器里返回出結(jié)果, 并賦值給Label
具體的demo鏈接附在下面了, 有興趣的可以看一下, 非常簡單的
demo鏈接