成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

iOS導(dǎo)航欄控制的示例分析

小編給大家分享一下iOS導(dǎo)航欄控制的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

10年積累的網(wǎng)站建設(shè)、成都網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有朝陽免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

1.導(dǎo)航欄的顯示與隱藏

導(dǎo)航欄的顯示與隱藏,分兩種情況:

1.從不顯示導(dǎo)航欄的頁面push到顯示導(dǎo)航欄的頁面。

2.從顯示導(dǎo)航欄的頁面Push到不顯示導(dǎo)航欄的頁面。

注意:

1.如果導(dǎo)航欄不顯示時(shí),系統(tǒng)的側(cè)滑返回功能無效。

2.雖然側(cè)滑返回功能無效,但是導(dǎo)航欄的 .interactivePopGestureRecognizer.delegate還是存在的。

針對以上兩種情況分別處理,整個(gè)Push過程都假設(shè)是從A頁面跳轉(zhuǎn)到B頁面

1.1 從不顯示導(dǎo)航欄的頁面Push到顯示導(dǎo)航欄的頁面。

關(guān)于導(dǎo)航欄的顯示,是否順滑,是通過如下兩個(gè)方法來控制。

// 不顯示動(dòng)畫,導(dǎo)航欄顯示就比較突兀[self.navigationController setNavigationBarHidden:YES];// 顯示動(dòng)畫,在側(cè)滑時(shí),導(dǎo)航欄顯示就比較順滑[self.navigationController setNavigationBarHidden:YES animated:YES];

所以,做法是:

A頁面:

- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.navigationController setNavigationBarHidden:YES animated:YES];}

B頁面:

- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.navigationController setNavigationBarHidden:NO animated:YES];}

1.2 從顯示導(dǎo)航欄的頁面跳轉(zhuǎn)到不顯示導(dǎo)航欄的頁面

這種情況的做法如下:

A頁面:

- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.navigationController setNavigationBarHidden:NO animated:YES];}

B頁面:

// 在頁面將要出現(xiàn)時(shí),記錄原始側(cè)滑手勢代理對象,并將手勢代理設(shè)置為當(dāng)前頁面- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; self.interactivePopDelegate = self.navigationController.interactivePopGestureRecognizer.delegate; self.navigationController.interactivePopGestureRecognizer.delegate = self; [self.navigationController setNavigationBarHidden:YES animated:YES];}// 在頁面消失時(shí),還原側(cè)滑手勢代理對象- (void)viewDidDisappear:(BOOL)animated{ [super viewDidDisappear:animated]; self.navigationController.interactivePopGestureRecognizer.delegate = self.interactivePopDelegate; self.interactivePopDelegate = nil;}// 實(shí)現(xiàn)手勢代理,為了防止影響其他手勢,可以判斷一下手勢類型- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ if ([gestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) { return YES; } ...... 其他手勢的處理 return NO;}

2.統(tǒng)一重寫導(dǎo)航欄返回按鈕

有時(shí)候,我們可能需要統(tǒng)一工程中的返回按鈕樣式,比如都是 箭頭+返回 或者都是 箭頭。

方案有兩種:

1.創(chuàng)建一個(gè)BaseViewController,然后統(tǒng)一設(shè)置navigationItem.leftBarButtonItem。

2.重寫導(dǎo)航控制器的Push方法,在push之前,設(shè)置navigationItem.backBarButtonItem。

注意:

如果重寫了導(dǎo)航欄的leftBarButtonItem,那么側(cè)滑返回功能也就失效了,需要側(cè)滑返回功能需要自己處理。

第一種方案比較簡單就不做贅述了,第二種方案是這樣的:

自定義導(dǎo)航控制器,然后重寫如下方法:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{ UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStyleDone target:nil action:nil]; viewController.navigationItem.backBarButtonItem = backItem; [super pushViewController:viewController animated:animated];}

如果不需要返回這兩個(gè)字,只需要這樣寫就好。

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{ UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:nil style:UIBarButtonItemStyleDone target:nil action:nil]; viewController.navigationItem.backBarButtonItem = backItem; [super pushViewController:viewController animated:animated];}

3.監(jiān)聽返回按鈕的點(diǎn)擊事件

在有些場景,我們需要監(jiān)聽返回按鈕的事件。比如,當(dāng)頁面用戶輸入了一些內(nèi)容后,用戶要點(diǎn)擊返回,想要回到上一個(gè)頁面時(shí),提醒用戶是否要緩存已經(jīng)輸入的內(nèi)容。

如果我們重寫了導(dǎo)航欄的返回按鈕,那么處理這種情況就很Easy,不做贅述了。

但是,如果我們沒有重寫過系統(tǒng)的返回按鈕,想要處理這種情況就比較麻煩,但是也是可以處理的。

處理步驟如下:

1.首先創(chuàng)建一個(gè)UIViewController的類別,頭文件(.h)的內(nèi)容如下:

@protocol BackItemProtocol <NSObject>- (BOOL)navigationShouldPopWhenBackButtonClick;@end@interface UIViewController (BackItem)<BackItemProtocol>@end@interface UINavigationController (BackItem)@end

包含一個(gè)協(xié)議、UIViewController的類別、UINavigationController的類別。

然后,實(shí)現(xiàn)文件(.m)如下:

#import "UIViewController+BackItem.h"@implementation UIViewController (BackItem)- (BOOL)navigationShouldPopWhenBackButtonClick{ return YES;}@end@implementation UINavigationController (BackItem)// 這個(gè)其實(shí)是導(dǎo)航欄的協(xié)議方法,在這里重寫了- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item{ if([self.viewControllers count] < [navigationBar.items count]) { return YES; } BOOL shouldPop = YES; UIViewController *vc = [self topViewController]; if([vc respondsToSelector:@selector(navigationShouldPopWhenBackButtonClick)]) { shouldPop = [vc navigationShouldPopWhenBackButtonClick]; } if (shouldPop) { dispatch_async(dispatch_get_main_queue(), ^{ [self popViewControllerAnimated:YES]; }); } else { for(UIView *subview in [navigationBar subviews]) { if(subview.alpha < 1) { [UIView animateWithDuration:.25 animations:^{  subview.alpha = 1; }]; } } } return NO;}@end

默認(rèn)是,不需要處理返回按鈕的事件,直接使用系統(tǒng)的pop方法。

但是,如果我們需要在用戶點(diǎn)擊返回按鈕時(shí),彈窗提示,那就需要導(dǎo)入這個(gè)類別。

然后,重寫一個(gè)方法:

- (BOOL)navigationShouldPopWhenBackButtonClick{ BOOL isFlag = 輸入框不為空等等條件 if (isFlag) { UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:nil message:@"是否保存修改" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { // 這里延時(shí)執(zhí)行是因?yàn)閁IAlertController阻塞UI,可能會(huì)導(dǎo)致動(dòng)畫的不流暢 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.navigationController popViewControllerAnimated:YES]; }); }]; UIAlertAction *saveAction = [UIAlertAction actionWithTitle:@"保存" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { // 這里延時(shí)執(zhí)行是因?yàn)閁IAlertController阻塞UI,可能會(huì)導(dǎo)致動(dòng)畫的不流暢 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self rightClick]; }); }]; [alertVC addAction:cancelAction]; [alertVC addAction:saveAction]; [self presentViewController:alertVC animated:YES completion:nil]; return NO; } return YES;}

4.導(dǎo)航控制器的頁面跳轉(zhuǎn)方式

安卓中的頁面跳轉(zhuǎn)有四種方式: standard、singleTop、singleTask、singleInstance。

例如singleTask,在做IM類App,跳轉(zhuǎn)到聊天室的場景,就非常有用,可以保證控制器棧中只有一個(gè)聊天室,避免返回時(shí)層級(jí)太深。

iOS端如果要仿這個(gè)效果的話,可以利用導(dǎo)航控制器的API:

- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated

首先,為UINavigationController 創(chuàng)建一個(gè)類別。

比如:

UINavigationController+HLPushAndPop.hUINavigationController+HLPushAndPop.m

然后,新增幾個(gè)方法:

拿兩個(gè)方法來舉例

- (void)hl_pushSingleViewController:(UIViewController *)viewController  animated:(BOOL)animated;- (void)hl_pushSingleViewController:(UIViewController *)viewController  parentClass:(Class)parentClass  animated:(BOOL)animated;

再然后,實(shí)現(xiàn)方法:

實(shí)現(xiàn)步驟:

  1. 創(chuàng)建新的數(shù)組復(fù)制導(dǎo)航控制器原來的堆棧中的控制器。在原始堆棧數(shù)組中判斷是否存在該類型的控制器,如果存在記錄其索引。在復(fù)制的數(shù)組中將索引及上方所有控制器移除。把將要push出來的控制器添加到復(fù)制的數(shù)組中。將新的控制器數(shù)組設(shè)置為導(dǎo)航控制器的棧數(shù)組,根據(jù)參數(shù)判斷是否要顯示動(dòng)畫。

我這邊做了一些發(fā)散,因?yàn)橐恍╊惪赡軙?huì)有很多子類,那么想要保證父類以及子類的實(shí)例都只有一個(gè),所以將方法做了改進(jìn)。

- (void)hl_pushSingleViewController:(UIViewController *)viewController  animated:(BOOL)animated{ [self hl_pushSingleViewController:viewController parentClass:viewController.class animated:animated];}- (void)hl_pushSingleViewController:(UIViewController *)viewController  parentClass:(Class)parentClass  animated:(BOOL)animated{ if (!viewController) { return; } // 如果要push的界面不是 parentClass以及其子類的實(shí)例,則按照方法1處理 if (![viewController isKindOfClass:parentClass]) { [self hl_pushSingleViewController:viewController animated:animated]; return; } // 判斷 導(dǎo)航控制器堆棧中是否有parentClass以及其子類的實(shí)例 NSArray *childViewControllers = self.childViewControllers; NSMutableArray *newChildVCs = [[NSMutableArray alloc] initWithArray:childViewControllers]; BOOL isExit = NO; NSInteger index = 0; for (int i = 0; i < childViewControllers.count; i++) { UIViewController *vc = childViewControllers[i]; if ([vc isKindOfClass:parentClass]) { isExit = YES; index = i; break; } } // 如果不存在,則直接push if (!isExit) { [self pushViewController:viewController animated:animated]; return; } // 如果存在,則將該實(shí)例及上面的所有界面全部彈出棧,然后將要push的界面放到棧頂。 for (NSInteger i = childViewControllers.count - 1; i >= index; i--) { [newChildVCs removeObjectAtIndex:i]; } [newChildVCs addObject:viewController]; viewController.hidesBottomBarWhenPushed = (newChildVCs.count > 1); [self setViewControllers:newChildVCs animated:animated];}

當(dāng)然了,除了上面這些場景,還可以擴(kuò)展出一些其他的場景,比如我們期望將要push出來的控制器再某個(gè)棧中控制器的后面或者前面,這樣當(dāng)點(diǎn)擊返回或者側(cè)滑時(shí),就直接回到了指定頁面了。

或者我們知道將要返回的頁面的類型,直接pop回指定頁面。

以上是“iOS導(dǎo)航欄控制的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

當(dāng)前標(biāo)題:iOS導(dǎo)航欄控制的示例分析
文章URL:http://jinyejixie.com/article20/iisgco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、自適應(yīng)網(wǎng)站、企業(yè)建站、定制開發(fā)域名注冊、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司
安顺市| 左权县| 贵阳市| 馆陶县| 孝昌县| 和田市| 闸北区| 长子县| 武宁县| 宝清县| 邳州市| 定兴县| 米林县| 巴中市| 鹰潭市| 昌平区| 上蔡县| 廊坊市| 政和县| 鹤庆县| 如皋市| 永善县| 密山市| 巨野县| 荥阳市| 南岸区| 色达县| 自治县| 通化市| 平定县| 吕梁市| 新和县| 隆尧县| 湘西| 喀喇| 江川县| 乐山市| 安化县| 胶州市| 木里| 宁乡县|