ios小貼士-自定義導(dǎo)航欄返回按鈕并且保留滑動(dòng)返回手勢(shì)

在ios中,系統(tǒng)提供的導(dǎo)航欄返回按鈕,會(huì)自動(dòng)包含許多其他我們可能用不到的View導(dǎo)致最后呈現(xiàn)的效果不如所愿,最常見(jiàn)的就是返回按鈕所占的位置太大了,比如這樣:

返回按鈕占位太大

因?yàn)閁IBarButtonItem是一個(gè)包裹嚴(yán)密的類(lèi),它將UIView包裹在他的內(nèi)部,使得我們沒(méi)辦法很方便地去獲取或者修改其中真正的Button(當(dāng)然我們可以用Runtime,KVC的方式來(lái)做,但我覺(jué)得還是稍顯麻煩).
因此我們通常都用自定義的方法來(lái)修改返回按鈕,但如果只是用[[UIBarButtonItem alloc] initWithCustomView:customBtn];來(lái)修改的話是無(wú)法使返回按鈕右邊的空隙減小的.
在系統(tǒng)的UIBarButtonSystemItem中有一個(gè)UIBarButtonSystemItemFixedSpace,它就是用來(lái)控制Item之間距離的,我們將它放在各個(gè)Item之間,并且將其width定為負(fù)數(shù),便可以使得Item之間的間隔縮小了,由于系統(tǒng)默認(rèn)的backItem距離最左邊還是有一些像素的間隔,如果需要縮短距離屏幕左邊的距離,那么就是按鈕的左右各需要一個(gè)UIBarButtonSystemItemFixedSpace,代碼如下

    UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [leftBtn setImage:[UIImage imageNamed:@"nav_back_icon"] forState:UIControlStateNormal];
    [leftBtn addTarget:self action:@selector(backNavAction) forControlEvents:UIControlEventTouchUpInside];
    leftBtn.frame = CGRectMake(-20, 0, 30, 30);
    UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
    UIBarButtonItem *leftSpace1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    leftSpace1.width = -20;
    UIBarButtonItem *leftSpace2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    leftSpace2.width = -20;
    self.navigationItem.leftBarButtonItems = @[leftSpace1,leftItem,leftSpace2];

這樣,就達(dá)到我們想要的效果了:

調(diào)整后的返回按鈕

但是現(xiàn)在有一個(gè)新的問(wèn)題,我們的滑動(dòng)返回上級(jí)頁(yè)面的手勢(shì)沒(méi)了.在UINavigationController的屬性中,我們可以找到一個(gè)手勢(shì)interactivePopGestureRecognizer,這個(gè)手勢(shì),就是我們滑動(dòng)返回的手勢(shì),打印這個(gè)代理self.navigationController.interactivePopGestureRecognizer.delegate得到結(jié)果:

默認(rèn)的滑動(dòng)返回手勢(shì)代理

我們可以通過(guò)將手勢(shì)的代理設(shè)置為控制器本身來(lái)重新激活滑動(dòng)返回手勢(shì):
self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;但是這又會(huì)帶來(lái)新的問(wèn)題,當(dāng)你返回上級(jí)頁(yè)面后(實(shí)際上還是同一個(gè)UINavigationController)會(huì)無(wú)法響應(yīng)所有的Action,所以你需要將代理重新還給原主人:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.oldNavGesDelegate = self.navigationController.interactivePopGestureRecognizer.delegate;
    self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.navigationController.interactivePopGestureRecognizer.delegate = self.oldNavGesDelegate;
}

這樣我們就實(shí)現(xiàn)了既自定義返回按鈕,又保留了滑動(dòng)返回手勢(shì).

最后編輯于
?著作權(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)容