OC -> 獲取全局的 Pop 和 Present 操作

說明:
項(xiàng)目中我們可能會(huì)針對全局的 push桦卒,pop邑跪,present播瞳,dismiss 等視圖轉(zhuǎn)場進(jìn)行操作比驻;
例如:
* 給 push/present 的下一級視圖一個(gè)返回按鈕。
* 給 push/present 的過程中隱藏所有的 tabbar敷硅。
* 給 push/present 的時(shí)候自定義一個(gè)轉(zhuǎn)場動(dòng)畫怎棱。
。拥诡。触趴。。渴肉。針對視圖轉(zhuǎn)換之間進(jìn)行的操作

Push Pop

大家都知道 push 和 pop 操作是有導(dǎo)航控制器來進(jìn)行控制的冗懦,所以這里我們講一個(gè)在 push 界面的時(shí)候?yàn)橄乱患壍膶?dǎo)航控制器進(jìn)行添加返回按鈕和對 tabbar 的隱藏。

1.0 創(chuàng)建 TabbarController 自定義 NavigationController仇祭,設(shè)置自定義的 NavigationController 為 TabBarController 的 NavigationController

    [self setupChildViewController:[[KlqNavViewController alloc] initWithRootViewController:[[KlqOneViewController alloc] init]] title:@"test1" image:@"tabbar_home_icon" selectedImage:@"tabbar_home_select_icon"];
    [self setupChildViewController:[[KlqNavViewController alloc] initWithRootViewController:[[KlqTwoViewController alloc] init]] title:@"test2" image:@"tabbar_counters_icon" selectedImage:@"tabbar_counters_select_icon"];
    [self setupChildViewController:[[KlqNavViewController alloc] initWithRootViewController:[[KlqThreeViewController alloc] init]] title:@"test4" image:@"tabbar_instr_icon" selectedImage:@"tabbar_instu_select_icon"];
    [self setupChildViewController:[[KlqNavViewController alloc] initWithRootViewController:[[KlqFourViewController alloc] init]] title:@"test5" image:@"tabbar_mine_icon" selectedImage:@"tabbar_mine_select_icon"];

在 導(dǎo)航控制器進(jìn)行 push 操作的時(shí)候

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (self.childViewControllers.count > 0) {
        UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [backButton setTitle:@"返回" forState:UIControlStateNormal];
        [backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
        viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        viewController.hidesBottomBarWhenPushed = YES;
    }
    [super pushViewController:viewController animated:YES];//這里進(jìn)行下簡單的說明披蕉,放到后面和放到前面是一樣子的,但是要注意的是如果放到前面的話乌奇,if 判斷中的 self.choildViewControllers 就要大于1才行了没讲。
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    return [super popViewControllerAnimated:YES];
}
通過這兩個(gè)方法可以攔截到在自定義的 navigationController 導(dǎo)航控制器控制的所有的 viewControlelr 發(fā)生的 push 和 pop 方法,這時(shí)候就可以在這里面對返回按鈕或者自定義push 動(dòng)畫進(jìn)行操作礁苗。

Present Dismiss

說完了 push 和 pop 操作食零,我們這時(shí)候在說下如果獲取到全局的 present 和 dismiss 操作,首先要了解的是我們的 present 和 dismiss 操作是不受導(dǎo)航控制器來進(jìn)行控制的寂屏。因此我們不能夠在導(dǎo)航控制器中寫 present 和 dismiss 操作贰谣,我們用到的方法是 hook 編程,即用到 objective 中的Method Swizzling 來獲取到 present 和 dismiss 方法迁霎,對它們進(jìn)行轉(zhuǎn)換吱抚,從而實(shí)現(xiàn)我們的需求。
Method Swizzling 方法的原理考廉,根本原理就是在程序運(yùn)行期間利用 IMP 和 SEL 動(dòng)態(tài)的給兩個(gè)方法進(jìn)行互換秘豹。

  1. IMP -> 就是指向一個(gè)方法實(shí)現(xiàn)的指針,大家要知道 OC 中方法在編譯期間會(huì)根據(jù) runtime 中的操作將方法保存到內(nèi)存中昌粤,因此我們調(diào)用方法的時(shí)候既绕,就需要根據(jù)方法的指針來對方法進(jìn)行調(diào)用。
  2. SEL -> 我們可以看到 objc/runtime.h 文件中的 objc_method 結(jié)構(gòu)體中是這么寫的涮坐,方法調(diào)用的時(shí)候會(huì)通過SEL找到 objc_method 結(jié)構(gòu)體凄贩,從而找到方法的 IMP指針。
struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
}        

下面我們看代碼:這里我們展示的是獲取到 present 的操作然后自定義下 present 的動(dòng)畫袱讹。

1. 我們這邊定義了一個(gè) ViewController 的 Category 來進(jìn)行對 ViewController 的擴(kuò)展疲扎。從而達(dá)到對 ViewController 的所有的方法的擴(kuò)展。
2. 在 viewController Category 中重寫 load 方法
+ (void)load{
    [super load];
    Method  fromMethod = class_getInstanceMethod([self class], @selector(presentViewController:animated:completion:));
    Method  toMethod   = class_getInstanceMethod([self class], @selector(swizzlingpresentViewController:animated:completion:));
    if (!class_addMethod([self class], @selector(viewDidLoad), method_getImplementation(toMethod), method_getTypeEncoding(toMethod))) {
        method_exchangeImplementations(fromMethod, toMethod);
    }
}

3.重定義的 present 方法
- (void)swizzlingpresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    //攔截到用戶的所有的 present 然后對視圖等信息進(jìn)行修改,調(diào)整椒丧。
    viewControllerToPresent.transitioningDelegate = self;
    [self swizzlingpresentViewController:viewControllerToPresent animated:YES completion:nil];
}
4.自定義模態(tài)方法 ShowMBTransitionAnimation
#pragma mark - TransitioningDelegate
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    ShowMBTransitionAnimation *showMBTransition = [ShowMBTransitionAnimation transitionWithType:ShowMBTransitionAnimationPresentType];
    showMBTransition.toViewHeight               = 500;
    return showMBTransition;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    ShowMBTransitionAnimation *dismissMBTransition = [ShowMBTransitionAnimation transitionWithType:ShowMBTransitionAnimationDismissType];
    dismissMBTransition.toViewHeight               = 500;
    return dismissMBTransition;
}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壹甥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子壶熏,更是在濱河造成了極大的恐慌句柠,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棒假,死亡現(xiàn)場離奇詭異俄占,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)淆衷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渤弛,“玉大人祝拯,你說我怎么就攤上這事∷希” “怎么了佳头?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晴氨。 經(jīng)常有香客問我康嘉,道長,這世上最難降的妖魔是什么籽前? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任亭珍,我火速辦了婚禮,結(jié)果婚禮上枝哄,老公的妹妹穿的比我還像新娘肄梨。我一直安慰自己,他們只是感情好挠锥,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布众羡。 她就那樣靜靜地躺著,像睡著了一般蓖租。 火紅的嫁衣襯著肌膚如雪粱侣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天蓖宦,我揣著相機(jī)與錄音齐婴,去河邊找鬼。 笑死稠茂,一個(gè)胖子當(dāng)著我的面吹牛尔店,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼嚣州,長吁一口氣:“原來是場噩夢啊……” “哼鲫售!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起该肴,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤情竹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后匀哄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秦效,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年涎嚼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阱州。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,918評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡法梯,死狀恐怖苔货,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情立哑,我是刑警寧澤夜惭,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站铛绰,受9級特大地震影響诈茧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捂掰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一敢会、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧这嚣,春花似錦走触、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卧土,卻和暖如春惫皱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尤莺。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工旅敷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颤霎。 一個(gè)月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓媳谁,卻偏偏與公主長得像涂滴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子晴音,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評論 2 361

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉柔纵,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,734評論 0 9
  • 我們常常會(huì)聽說 Objective-C 是一門動(dòng)態(tài)語言,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢锤躁?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,199評論 0 7
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 767評論 0 1
  • runtime 和 runloop 作為一個(gè)程序員進(jìn)階是必須的搁料,也是非常重要的, 在面試過程中是經(jīng)常會(huì)被問到的系羞, ...
    made_China閱讀 1,211評論 0 7
  • Objective-C語言是一門動(dòng)態(tài)語言郭计,它將很多靜態(tài)語言在編譯和鏈接時(shí)期做的事放到了運(yùn)行時(shí)來處理。這種動(dòng)態(tài)語言的...
    有一種再見叫青春閱讀 590評論 0 3