標籤:
使用運行時擷取系統的屬性:使用自己的手勢修改系統內建的手勢
有的時候我需要實現一個功能,但是沒有想到很好的方法或者想到了方法只是那個方法實現起來太麻煩,一或者確實為了裝逼,我們就會想到iOS開發中最牛逼的技術運行時(Runtime)
關於運行時這裡就不多說了,請查看筆者之前搬過來了精選文章,這裡主要是怎麼在實際開發中使用運行時實現我們想要的功能。
比如,在iOS開發中有這樣一個問題,關於導覽列中我們點擊一個按鈕會跳到對應的子控制器,但是這裡問題就來了,我們在對應的字控制器中可以點擊對應的back按鈕實現返回,但是如果使用者使用的是滑動的話,這裡就會出問題,除什麼問題呢?
問題就是:使用者只能在對應的子控制器中的最左邊滑動返回,音文一般我們都是實現全域介面滑動都可以的,所以這裡我要解決的就是這樣問題。
這裡的思路是:
修改系統內建的手勢滑動方法,我自己來實現,並且增加一些相應的功能。
好了下面來看看怎麼使用這種牛逼的技術
一:首先我們需要匯入執行階段程式庫
二:然後使用runtime的方式列印系統對應的成員屬性
擷取成員變數,知道屬性名稱,
怎麼通過運行時機制擷取屬性值,首先得要擷取屬性的名,通過KVC擷取值
擷取target,需要使用運行時機制,遍曆出類裡面所有屬性名稱
利用運行時擷取屬性名稱,只能擷取當前類下的所有屬性名稱,並不能擷取它的子類或者父類。
copyIvarList:擷取成員屬性列表
Class:擷取哪個類下面的屬性
outCount:這個類有多少個成員屬性,成員屬性的總數
1 /** 2 3 * 列印屬性 4 5 */ 6 7 unsigned int count = 0; 8 9 // 擷取UIGestureRecognizer裡所有的成員屬性10 11 Ivar *ivars = class_copyIvarList([UIGestureRecognizer class], &count);12 13 14 15 for (int i = 0; i < count; i++) {16 17 // 擷取成員屬性18 19 Ivar ivar = ivars[i];20 21 22 23 // 擷取成員屬性的屬性名稱24 25 NSString *name = @(ivar_getName(ivar));26 27 28 29 // NSLog(@"%@",name);30 31 }
三:由於我們需要改變的死系統對應的手勢,所以這裡需要分析一下系統手勢的方法和對應的屬性,並且把他替換掉
- 系統的滑動手勢觸發的時候,會調用Target的action,去做滑動返回的事情(action),
- 擷取系統滑動返回的target和action
// action:=> handleNavigationTransition:
UIScreenEdgePanGestureRecognizer *gesture = self.interactivePopGestureRecognizer;
四:從上面運行時方法列印出來的屬性我們可以知道,系統對應的手勢方法值是 _targets,所以我們可以使用KVC的方式改掉他。
1 NSArray *targets = [gesture valueForKeyPath:@"_targets"]; 2 3 4 5 id gestureRecognizer = targets[0]; 6 7 8 9 id target = [gestureRecognizer valueForKeyPath:@"_target"];10 11 12 13 // NSLog(@"%@",target);14 15 16 17 self.interactivePopGestureRecognizer.enabled = NO;18 19 20 21 // 借用系統的滑動手勢的功能,當觸發自己的滑動手勢的時候,調用系統的滑動返回功能22 23 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];24 25 26 27 pan.delegate = self;28 29 30 31 [self.view addGestureRecognizer:pan];32 33
iOS開發——運行時OC篇&使用運行時擷取系統的屬性:使用自己的手勢修改系統內建的手勢