iOS Navigation導(dǎo)航欄

在iOS開(kāi)發(fā)過(guò)程中,導(dǎo)航欄是最為經(jīng)常用到的控件,處理不好總會(huì)出現(xiàn)一些瑕疵或者bug,寫(xiě)這篇文章旨在為自己記錄平時(shí)所用有關(guān)Navigation一些操作或者說(shuō)是小技巧。
下文涉及到的push邏輯都是從A頁(yè)面push到B頁(yè)面,我會(huì)直接以A、B介紹

一、關(guān)于返回Item

默認(rèn)從A—>B(push),B中返回按鈕的title顯示的是A的標(biāo)題,當(dāng)A的標(biāo)題過(guò)長(zhǎng),會(huì)顯示返回(back)。A標(biāo)題長(zhǎng)同時(shí)B標(biāo)題也長(zhǎng),就會(huì)出現(xiàn)B標(biāo)題被擠到右邊了,這就尷尬了。如下圖


B標(biāo)題未正常顯示

網(wǎng)上有說(shuō)在A的viewWillDisappear將A的標(biāo)題設(shè)置成空的,在viewDidAppear方法中再將標(biāo)題設(shè)置原來(lái)的,但是這個(gè)在手勢(shì)側(cè)滑過(guò)程中顯示會(huì)有問(wèn)題,這里就不做演示了。
這里提供一個(gè)解決方案:讓A控制器繼承自BaseViewController(自己創(chuàng)建的控制器),在BaseViewController做以下操作:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"返回"
                                                                 style:UIBarButtonItemStyleDone
                                                                target:self
                                                                action:nil];
    self.navigationItem.backBarButtonItem = backItem;
}
正常顯示

有時(shí)我們并不需要顯示title,在上圖中的“返回”設(shè)置成 nil 就可以解決問(wèn)題。當(dāng)然我們剛才并沒(méi)有改變返回的圖片都是用系統(tǒng)默認(rèn)的,如果只是單純的顯示自定義的返回圖標(biāo)(需求就是這么樣,有什么辦法),那么問(wèn)題來(lái)了,怎么設(shè)置比較合理。以
下給出幾種方案:

1、設(shè)置navigationItem的leftBarButtonItem(不推薦)
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_back"]
                                                             style:UIBarButtonItemStylePlain
                                                            target:self
                                                            action:@selector(p_actionBack)];
self.navigationItem.leftBarButtonItem = backItem;
自定義返回按鈕

只是添加leftBarButtonItem側(cè)滑手勢(shì)被禁止了,圖標(biāo)離左側(cè)有一定距離,經(jīng)過(guò)如下修改:

- (void)p_addBackItem {
    //間隙
    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil];
    //spaceItem寬度為負(fù)值,相當(dāng)于左移
    spaceItem.width = -8;
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_back"]
                                                                 style:UIBarButtonItemStylePlain
                                                                target:self
                                                                action:@selector(p_actionBack)];
    self.navigationItem.leftBarButtonItems = @[spaceItem, backItem];
    //設(shè)置代理,添加leftBarButtonItem系統(tǒng)的側(cè)滑手勢(shì)會(huì)被禁
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
       self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}
 - (void)p_actionBack {
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
}
自定義
2、將title移出視圖外,從而達(dá)到隱藏的效果(推薦,作用范圍全局)

注意:這個(gè)需要在AppDelegate設(shè)置才有效

- (void)initBars {
    UIImage *backImage = [UIImage imageNamed:@"navigation_back"];
    UINavigationBar *navigationbar = [UINavigationBar appearance];
    [navigationbar setBackIndicatorImage:backImage];
    [navigationbar setBackIndicatorTransitionMaskImage:backImage];
    [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60)
                                                         forBarMetrics:UIBarMetricsDefault];
}
設(shè)置偏移量,替換系統(tǒng)返回按鈕

上一頁(yè)標(biāo)題過(guò)長(zhǎng)

對(duì)比可以發(fā)現(xiàn),第一張圖是標(biāo)題比較短的時(shí)候顯示正常,第二張圖是標(biāo)題比較長(zhǎng)的時(shí)候標(biāo)題被往右擠了。


視圖下查看
這個(gè)方法只是將返回Item的title移出,寬度并沒(méi)有改變,所以在使用這個(gè)方法時(shí)一定要注意,我一般是配合一開(kāi)始提到的搭配使用。如果有更好的解決方法可以留言告知,不勝感激。

二、Navigation顯示或隱藏

項(xiàng)目中一般有一兩個(gè)頁(yè)面比較特殊,需要隱藏導(dǎo)航欄或者導(dǎo)航欄需要根據(jù)滑動(dòng)漸變,如登錄頁(yè)面需要隱藏導(dǎo)航欄。隱藏簡(jiǎn)單,拿起鍵盤(pán)就是干。

1、隱藏導(dǎo)航欄

使用[self.navigationController setNavigationBarHidden:NO animated:YES] 側(cè)滑手勢(shì)會(huì)被禁,所以需要加代理開(kāi)啟手勢(shì)

- (void)viewDidLoad {
    [super viewDidLoad];
    //設(shè)置代理
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    //會(huì)導(dǎo)致側(cè)滑手勢(shì)被禁
    [self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    //如果該控制器沒(méi)有上級(jí)控制器,建議將使用[self.navigationController setNavigationBarHidden:NO animated:animated] 效果會(huì)更好點(diǎn)
    [self.navigationController setNavigationBarHidden:NO animated:NO];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
}
2、導(dǎo)航欄漸變

介紹兩個(gè)方法:

//隱藏導(dǎo)航欄,但不隱藏上面的Item
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init]
                                              forBarMetrics:UIBarMetricsDefault];
//隱藏導(dǎo)航欄底部那條線
[self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];

這個(gè)不做演示,推薦一個(gè)三方 LTNavigationBar

三、自定義TitleView

直接上代碼

UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
switchView.center = titleView.center;
[titleView addSubview:switchView];
self.navigationItem.titleView = titleView;
自定義TitleView
最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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