亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS導航欄控制的一些總結

2020-07-26 02:19:30
字體:
來源:轉載
供稿:網友

前言

許久不寫UI,對UI的很多東西都生疏了,最近使用導航欄的各種場景做一些總結。

1.導航欄的顯示與隱藏

導航欄的顯示與隱藏,分兩種情況:

1.從不顯示導航欄的頁面push到顯示導航欄的頁面。

2.從顯示導航欄的頁面Push到不顯示導航欄的頁面。

注意:

1.如果導航欄不顯示時,系統的側滑返回功能無效。

2.雖然側滑返回功能無效,但是導航欄的 .interactivePopGestureRecognizer.delegate還是存在的。

針對以上兩種情況分別處理,整個Push過程都假設是從A頁面跳轉到B頁面

1.1 從不顯示導航欄的頁面Push到顯示導航欄的頁面。

關于導航欄的顯示,是否順滑,是通過如下兩個方法來控制。

// 不顯示動畫,導航欄顯示就比較突兀[self.navigationController setNavigationBarHidden:YES];// 顯示動畫,在側滑時,導航欄顯示就比較順滑[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 從顯示導航欄的頁面跳轉到不顯示導航欄的頁面

這種情況的做法如下:

A頁面:

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

B頁面:

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

2.統一重寫導航欄返回按鈕

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

方案有兩種:

1.創建一個BaseViewController,然后統一設置navigationItem.leftBarButtonItem。

2.重寫導航控制器的Push方法,在push之前,設置navigationItem.backBarButtonItem。

注意:

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

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

自定義導航控制器,然后重寫如下方法:

- (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];}

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

- (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.監聽返回按鈕的點擊事件

在有些場景,我們需要監聽返回按鈕的事件。比如,當頁面用戶輸入了一些內容后,用戶要點擊返回,想要回到上一個頁面時,提醒用戶是否要緩存已經輸入的內容。

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

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

處理步驟如下:

1.首先創建一個UIViewController的類別,頭文件(.h)的內容如下:

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

包含一個協議、UIViewController的類別、UINavigationController的類別。

然后,實現文件(.m)如下:

#import "UIViewController+BackItem.h"@implementation UIViewController (BackItem)- (BOOL)navigationShouldPopWhenBackButtonClick{ return YES;}@end@implementation UINavigationController (BackItem)// 這個其實是導航欄的協議方法,在這里重寫了- (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

默認是,不需要處理返回按鈕的事件,直接使用系統的pop方法。

但是,如果我們需要在用戶點擊返回按鈕時,彈窗提示,那就需要導入這個類別。

然后,重寫一個方法:

- (BOOL)navigationShouldPopWhenBackButtonClick{ BOOL isFlag = 輸入框不為空等等條件 if (isFlag) { UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:nil message:@"是否保存修改" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { // 這里延時執行是因為UIAlertController阻塞UI,可能會導致動畫的不流暢 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) { // 這里延時執行是因為UIAlertController阻塞UI,可能會導致動畫的不流暢 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.導航控制器的頁面跳轉方式

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

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

iOS端如果要仿這個效果的話,可以利用導航控制器的API:

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

首先,為UINavigationController 創建一個類別。

比如:

UINavigationController+HLPushAndPop.hUINavigationController+HLPushAndPop.m

然后,新增幾個方法:

拿兩個方法來舉例

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

再然后,實現方法:

實現步驟:

  1. 創建新的數組復制導航控制器原來的堆棧中的控制器。
  2. 在原始堆棧數組中判斷是否存在該類型的控制器,如果存在記錄其索引。
  3. 在復制的數組中將索引及上方所有控制器移除。
  4. 把將要push出來的控制器添加到復制的數組中。
  5. 將新的控制器數組設置為導航控制器的棧數組,根據參數判斷是否要顯示動畫。

我這邊做了一些發散,因為一些類可能會有很多子類,那么想要保證父類以及子類的實例都只有一個,所以將方法做了改進。

- (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以及其子類的實例,則按照方法1處理 if (![viewController isKindOfClass:parentClass]) { [self hl_pushSingleViewController:viewController animated:animated]; return; }  // 判斷 導航控制器堆棧中是否有parentClass以及其子類的實例 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; }  // 如果存在,則將該實例及上面的所有界面全部彈出棧,然后將要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];}

當然了,除了上面這些場景,還可以擴展出一些其他的場景,比如我們期望將要push出來的控制器再某個棧中控制器的后面或者前面,這樣當點擊返回或者側滑時,就直接回到了指定頁面了。

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

擴展出來的其他方法都在Demo中了,有興趣的可以看一下。

地址是:HLProject (本地下載)

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美福利小视频| 国产精品免费一区豆花| 精品国产精品三级精品av网址| 亚洲欧洲一区二区三区久久| 亚洲福利视频网站| 欧美日韩精品在线播放| 成人午夜在线视频一区| 久久久久这里只有精品| 日本久久久a级免费| 在线播放精品一区二区三区| 欧美精品国产精品日韩精品| 色狠狠av一区二区三区香蕉蜜桃| 国产精品久久网| 成人黄色av免费在线观看| 亚洲精品国偷自产在线99热| 韩国精品久久久999| 亚洲视频在线观看网站| 福利一区福利二区微拍刺激| 亚洲欧美在线免费观看| 欧美激情综合色| 久久久精品一区二区三区| 欧美电影在线观看高清| 日韩美女毛茸茸| 免费不卡欧美自拍视频| 日本午夜精品理论片a级appf发布| 欧美极品美女视频网站在线观看免费| 国产丝袜一区二区三区| 亚洲精品免费一区二区三区| 欧美精品一区二区免费| 亚洲天堂网在线观看| 日韩女优人人人人射在线视频| 久久久久久中文| 欧美大尺度激情区在线播放| 国产精品色悠悠| 国产成人精品久久| 久久99久久亚洲国产| 欧美高清无遮挡| 91美女福利视频高清| 亚洲成人精品视频| 97婷婷涩涩精品一区| 中文字幕亚洲无线码在线一区| 欧美精品www在线观看| 亚洲欧美另类人妖| 姬川优奈aav一区二区| 91亚洲精品视频| 亚洲经典中文字幕| 亚洲2020天天堂在线观看| 青草青草久热精品视频在线网站| 色综合久综合久久综合久鬼88| 国产日产欧美a一级在线| 5566日本婷婷色中文字幕97| 日韩欧美在线视频免费观看| 国产视频久久久久久久| 亚洲男人第一av网站| 国产精品久久97| 国外色69视频在线观看| 国产精品网红福利| 久久精品亚洲94久久精品| 正在播放亚洲1区| 中文字幕日韩精品在线| 日韩国产高清视频在线| 国产精品视频久久久久| 亚洲欧美综合另类中字| 一夜七次郎国产精品亚洲| 亚洲97在线观看| 国产香蕉一区二区三区在线视频| 亚洲欧美一区二区三区情侣bbw| 亚洲曰本av电影| 成人久久18免费网站图片| 日韩精品视频免费专区在线播放| 欧美中文字幕第一页| 久久久久久久久久久免费精品| 黑人巨大精品欧美一区二区三区| 久久99热精品这里久久精品| 欧美老女人性生活| 亚洲女在线观看| 97精品久久久中文字幕免费| 国产精品劲爆视频| 日韩美女写真福利在线观看| 久久婷婷国产麻豆91天堂| 精品色蜜蜜精品视频在线观看| 久久精品国产欧美亚洲人人爽| 亚洲女人天堂网| 97在线视频免费| 91av视频在线| 久久精品电影网| 欧美激情va永久在线播放| 亚洲精品xxx| 久久久精品免费视频| 久久综合国产精品台湾中文娱乐网| 麻豆一区二区在线观看| 亚洲欧美国产精品久久久久久久| 欧美激情精品久久久| 最近2019好看的中文字幕免费| 亚洲国产日韩欧美综合久久| 欧美在线观看网址综合| 国产女人18毛片水18精品| 亚洲成人网av| 日韩网站免费观看| 亚洲bt欧美bt日本bt| 中文字幕一区电影| 国产综合色香蕉精品| 中文字幕亚洲无线码在线一区| 久久精品男人天堂| 播播国产欧美激情| 久久久精品999| 亚洲欧美国产精品| 久久精品99久久香蕉国产色戒| 日韩成人在线网站| 久精品免费视频| 性欧美xxxx视频在线观看| 国产精品福利在线观看| 2019中文字幕在线观看| 久久九九精品99国产精品| 亚洲人成在线播放| 亚洲欧洲美洲在线综合| 成人网在线视频| 欧美日韩在线视频观看| 韩曰欧美视频免费观看| 亚洲欧美在线一区二区| 国产欧美日韩精品丝袜高跟鞋| www.欧美精品一二三区| 久久精品夜夜夜夜夜久久| 精品福利一区二区| 国产91在线播放| 欧美第一黄网免费网站| 在线精品国产成人综合| 亚洲精品综合久久中文字幕| 国产一区二区三区三区在线观看| 成人在线中文字幕| 亚洲 日韩 国产第一| 亚洲综合色激情五月| 亚洲欧美激情一区| 97久久久免费福利网址| 欧美一区深夜视频| 亚洲欧美在线第一页| 成人免费看吃奶视频网站| 久久人人爽人人爽人人片av高请| 永久555www成人免费| 欧美日韩国产123| 91手机视频在线观看| 欧美最猛性xxxxx(亚洲精品)| 久久不射热爱视频精品| 日本午夜在线亚洲.国产| 亚洲免费人成在线视频观看| 国产精品www| 国产亚洲欧洲高清| 久久久免费av| 日韩精品欧美国产精品忘忧草| 亚洲一区二区久久久久久久| 国产精品电影网站| 欧美大人香蕉在线| 日韩中文字幕亚洲| 69影院欧美专区视频| 欧美在线亚洲一区| 91国语精品自产拍在线观看性色| 77777亚洲午夜久久多人| 日韩成人在线视频观看| 伊人青青综合网站| 日韩中文字幕视频在线观看| 国内精品400部情侣激情| 欧美日韩国产在线| 精品国偷自产在线视频| 91久久在线播放|