UINavigationController的全屏pop之runtime探究

對之前一直寫一直用的功能石抡,來做個總結(jié)。
系統(tǒng)自帶的pop效果是輕掃左邊邊緣pop返回助泽,要實現(xiàn)的效果是輕掃全屏pop返回啰扛。

思路

要改變系統(tǒng)的效果,1.重寫嗡贺,2.設置系統(tǒng)提供的相關(guān)屬性(直接設置/通過KVC)

探究

首先隐解,我們先去UINavigationController.h源文件中找系統(tǒng)提供的方法或者屬性。@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;诫睬,interactivePopGestureRecognizer是只讀屬性厢漩,屬于UIGestureRecognizer這個類。因為是readonly的岩臣,所以我們無法重寫和自定義溜嗜,繼續(xù)點進去UIGestureRecognizer.h查看,有一個enabled屬性架谎,所以可以將enabled設置為NO炸宵,或者猜測是否有私有屬性可以通過KVC搞定的。
于是谷扣,log一下interactivePopGestureRecognizer一看究竟

NSLog(@"%@",self.navigationController.interactivePopGestureRecognizer);

打印結(jié)果

<UIScreenEdgePanGestureRecognizer: 0x7fd9a160cb30; state = Possible; enabled = NO; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fd9a1415480>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fd9a16003c0>)>>

通過log土全,interactivePopGestureRecognizer屬性其實是UIScreenEdgePanGestureRecognizer類,查看UIScreenEdgePanGestureRecognizer.h源文件会涎,繼承自UIPanGestureRecognizer裹匙,包含一個屬性edges,也就是所有邊緣末秃,從這個枚舉看出都是設置邊緣的概页,無法修改edges為全部

typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
    UIRectEdgeNone   = 0,
    UIRectEdgeTop    = 1 << 0,
    UIRectEdgeLeft   = 1 << 1,
    UIRectEdgeBottom = 1 << 2,
    UIRectEdgeRight  = 1 << 3,
    UIRectEdgeAll    = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);

所以,我們要做的是练慕,創(chuàng)建一個UIPanGestureRecognizer手勢惰匙,讓它的target和action執(zhí)行系統(tǒng)響應的方法,所以可以用runtime獲取系統(tǒng)手勢的target和action

unsigned int count = 0;
Ivar *var = class_copyIvarList([UIGestureRecognizer class], &count);
for (int i = 0; i < count; i++) {
    Ivar _var = *(var + i);
    NSLog(@"%s ------ %s",ivar_getName(_var),ivar_getTypeEncoding(_var));
}
打印結(jié)果

接下來铃将,可以通過KVC獲取_targets了

NSMutableArray *targets = [self.navigationController.interactivePopGestureRecognizer valueForKeyPath:@"_targets"];
NSLog(@"%@",targets);
/*
(
    "(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fdbf2e02110>)"
)
*/

_targets數(shù)組中就一個元素项鬼,雖然不知道什么類型,可以選擇用 id 接收劲阎。如果想繼續(xù)探究绘盟,那就打斷點看下控制臺,isa指向UIGestureRecognizerTarget私有類悯仙。


斷點調(diào)試
代碼

我們可以在自定義的NavigationController中添加以下代碼

@interface SSNavigationController ()<UIGestureRecognizerDelegate>

@end

@implementation SSNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self initGlobalPan];
}

-(void)initGlobalPan
{
    //取消系統(tǒng)自帶手勢
    self.interactivePopGestureRecognizer.enabled = NO;
    
    //獲取系統(tǒng)的手勢的target數(shù)組
    NSMutableArray *_targets = [self.interactivePopGestureRecognizer valueForKeyPath:@"_targets"];
    //獲取target
    id target = [[_targets firstObject] valueForKeyPath:@"_target"];
    //獲取action
    SEL action = NSSelectorFromString(@"handleNavigationTransition:");
    
    //創(chuàng)建一個與系統(tǒng)一樣的手勢 只把它的類改為UIPanGestureRecognizer
    UIPanGestureRecognizer *popRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget: target action: action];
    popRecognizer.delegate = self;
    //添加到系統(tǒng)手勢作用的view上
    UIView *gestureView = self.interactivePopGestureRecognizer.view;
    [gestureView addGestureRecognizer:popRecognizer];
}

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    //當前控制器為根控制器龄毡,pop動畫正在執(zhí)行的時候不允許手勢
    return self.viewControllers.count != 1 && ![[self valueForKeyPath:@"_isTransitioning"] boolValue];
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市雁比,隨后出現(xiàn)的幾起案子稚虎,更是在濱河造成了極大的恐慌,老刑警劉巖偎捎,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蠢终,死亡現(xiàn)場離奇詭異,居然都是意外死亡茴她,警方通過查閱死者的電腦和手機寻拂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丈牢,“玉大人祭钉,你說我怎么就攤上這事〖号妫” “怎么了慌核?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵距境,是天一觀的道長。 經(jīng)常有香客問我垮卓,道長垫桂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任粟按,我火速辦了婚禮诬滩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灭将。我一直安慰自己疼鸟,他們只是感情好,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布庙曙。 她就那樣靜靜地躺著空镜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矾利。 梳的紋絲不亂的頭發(fā)上姑裂,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音男旗,去河邊找鬼舶斧。 笑死,一個胖子當著我的面吹牛察皇,可吹牛的內(nèi)容都是我干的茴厉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼什荣,長吁一口氣:“原來是場噩夢啊……” “哼矾缓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起稻爬,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嗜闻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后桅锄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體琉雳,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年友瘤,在試婚紗的時候發(fā)現(xiàn)自己被綠了翠肘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡辫秧,死狀恐怖束倍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤绪妹,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布甥桂,位于F島的核電站,受9級特大地震影響邮旷,放射性物質(zhì)發(fā)生泄漏格嘁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一廊移、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧探入,春花似錦狡孔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至植旧,卻和暖如春辱揭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背病附。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工问窃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人完沪。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓域庇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親覆积。 傳聞我的和親對象是個殘疾皇子听皿,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容