迷人的 iOS導(dǎo)航條

一、backBarItem和 leftBarItem 傻傻分不清楚

關(guān)于系統(tǒng)的導(dǎo)航條里backBarItem和leftBarItem有什么區(qū)別,我看了 LonlyCat 的 iOS 側(cè)滑返回手勢(shì),寫得還算比較清楚。 自己學(xué)習(xí)了以后做了個(gè)總結(jié),Demo 的內(nèi)容覆蓋還有全局側(cè)滑框架FDFullscreenPopGesture的源碼中文詳解和自己項(xiàng)目中需求對(duì)源碼的理解,框架本身代碼量也比較少,如果覺得看得吃力可以參考我的 Demo。

1. backBarItem 和 leftBarItem,交互動(dòng)畫區(qū)別:
left and back.gif

有留意過微信的返回手勢(shì)效果嗎? 微信的返回手勢(shì)就是第一種,覆蓋了 leftBackItem,手勢(shì)返回的過程中,左上角的文字是漸暗的。

第二種效果就是 backBarItem 了,也是系統(tǒng)默認(rèn)的效果,會(huì)慢慢遠(yuǎn)離返回按鈕,然后 pop。

2. backBarItem 和 leftBarItem,代碼區(qū)別,假如 A要 push B, A --> B
  • leftBarItem:
    在 B 控制器中實(shí)現(xiàn)如下代碼,就可以覆蓋 leftBarItem
UIButton *lefuButton = [UIButton buttonWithType:UIButtonTypeCustom];
    lefuButton.titleLabel.font = [UIFont systemFontOfSize:17];
    [lefuButton setImage:[UIImage imageNamed:@"nav_back"] forState:UIControlStateNormal];
    [lefuButton setImage:[UIImage imageNamed:@"nav_back"] forState:UIControlStateHighlighted];
    [lefuButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [lefuButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
    [lefuButton setImageEdgeInsets:UIEdgeInsetsMake(0, -10, 0, 0)];
    [lefuButton setTitle:@"leftBarItem" forState:UIControlStateNormal] ;
    [lefuButton sizeToFit];
    [lefuButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    
    UIBarButtonItem *leftButtonItem = [[UIBarButtonItem alloc] initWithCustomView:lefuButton];
    
    self.navigationItem.leftBarButtonItem = leftButtonItem;
  • backBarItem:
    在 A(注意這里不是 B) 控制器中實(shí)現(xiàn)如下代碼,就可以覆蓋 backBarItem
 UIBarButtonItem *backItem = [[UIBarButtonItem alloc]init];
    backItem.title = @"backBarItem";
//如果使用了自己的返回圖片, 需要適當(dāng)調(diào)整文字和圖片的距離
    [backItem setBackButtonTitlePositionAdjustment:UIOffsetMake(8, 0) forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
    self.navigationItem.backBarButtonItem = backItem;

如果僅僅在 A 控制器中覆蓋 backBarButtonItem 的話,那 B 控制器中的返回圖片還是系統(tǒng)的, 如果想要替換成自己的返回圖片,就要在導(dǎo)航控制器中添加如下代碼,替換系統(tǒng)的backIndicatorImage

 UIImage *backImg = [UIImage imageNamed:@"nav_back"];
    backImg = [backImg imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    self.navigationBar.backIndicatorImage = backImg;
    self.navigationBar.backIndicatorTransitionMaskImage = backImg;
    

3. backBarItem 和leftBarItem , 在項(xiàng)目應(yīng)用中的區(qū)別:
  • 覆蓋leftBarItem

系統(tǒng)自帶的邊緣側(cè)滑手勢(shì)會(huì)失效,需要重新在導(dǎo)航控制器中設(shè)置邊緣返回手勢(shì)的代理為某個(gè)對(duì)象,可以在代理中處理邊緣側(cè)滑手勢(shì)

    self.interactivePopGestureRecognizer.delegate =  someObject;

優(yōu)點(diǎn)當(dāng)然是可以更靈活的處理 leftBarItem的點(diǎn)擊事件和 UI 方面;

  • 覆蓋backBarItem

系統(tǒng)自帶的邊緣側(cè)滑手勢(shì)會(huì)不會(huì)失效,但是想要靈活的處理 backBarItem 的事件那就不行了。

二、關(guān)于FDFullscreenPopGesture

這個(gè) sunny 開源的框架,解決了無論是覆蓋 leftBarItem 還是 backBarItem 的返回手勢(shì)問題, 并且把邊緣返回手勢(shì),改變成了全局返回手勢(shì),同時(shí)解決了控制器之間存在導(dǎo)航條是透明的情況,不同控制器之間的無縫銜接。

整個(gè)框架運(yùn)用分類 + runtime 的寫完,不用寫一行代碼就可以實(shí)現(xiàn)全局返回手勢(shì),因?yàn)?runtime 會(huì)調(diào)用分類的+load 方法,而且是后于類和子類調(diào)用??蚣苄Ч麍D如下:

FDFullScreen.gif

但是在實(shí)際開發(fā)中我的項(xiàng)目在導(dǎo)航條需要隱藏的控制器中,往下滑動(dòng)時(shí)候,導(dǎo)航條還需要漸變,因?yàn)镕DFullscreenPopGesture 是通過

self.fd_prefersNavigationBarHidden = YES;

這個(gè)控制器的屬性來隱藏導(dǎo)航條的,如果再在導(dǎo)航條上加上透明度漸變的效果,那來回 pop,push 其他控制器的時(shí)候根本無法好好處理導(dǎo)航條的隱藏和顯示,所以我在 demo 中,在需要漸變導(dǎo)航條的控制器中添加了一個(gè)假的導(dǎo)航條,這是一個(gè)很好的解決方式。

MYFDFullScreen.gif

附上Demo, Demo 中附有FDFullscreenPopGesture源碼中文詳解,因?yàn)樵创a為了簡(jiǎn)潔和方便,把所有分類都放到一個(gè)文件中,我為了能讓其更簡(jiǎn)單易懂,就把各個(gè)分類文件能分開就分開了, 雖然文件多了但是結(jié)構(gòu)更加清晰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容