需求是從不同頁(yè)面push過(guò)來(lái)要做不同的pop怕敬,有的直接返回上一級(jí),有的要返回到rootViewController。
介紹我想到的有兩種方式和遇到的問(wèn)題以及解決的辦法。
方式一:
自定義一個(gè)按鈕狡相,添加點(diǎn)擊事件,在事件中去自由的pop食磕,然后把這個(gè)自定義按鈕設(shè)置為導(dǎo)航欄的self.navigationItem.leftBarButtonItem尽棕。
存在的問(wèn)題:左滑返回的手勢(shì)失效了。
解決辦法:
第一步:在RootViewController的viewDidAppear中把self.navigationController.interactivePopGestureRecognizer.enabled = NO;
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// 解決自定義返回按鈕影響左滑手勢(shì)的問(wèn)題
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
第二步:
在push控制器前調(diào)用
// 解決自定義返回按鈕影響左滑手勢(shì)的問(wèn)題
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
}
方式二:
但是我的項(xiàng)目中用的都是系統(tǒng)的返回按鈕彬伦,如果自定義的話樣式會(huì)不統(tǒng)一滔悉,所以要用系統(tǒng)的返回按鈕。
存在的問(wèn)題:怎么攔截導(dǎo)航欄返回按鈕事件
解決辦法
聲明:此方法網(wǎng)上流傳已久媚朦,我只是搬運(yùn)工氧敢,記錄下來(lái)日戈。具體的作者我也不知道是誰(shuí)询张,向作者致敬。@此方法的第一位分享者
可能是http://stackoverflow.com/questions/1214965/setting-action-for-back-button-in-navigation-controller/19132881#19132881
可以為 UINavigatonController 創(chuàng)建一個(gè) Category浙炼,來(lái)定制navigationBar: shouldPopItem: 的邏輯份氧。這里需要注意的是,我們不需要去設(shè)置 delegate弯屈,因?yàn)?UINavigatonController 自帶的 UINavigationBar 的 delegate 就是導(dǎo)航欄本身蜗帜。這樣還有個(gè)問(wèn)題就是,那在實(shí)際的 Controller 里面怎么控制呢资厉?因此同樣需要對(duì) UIViewController 添加一個(gè) Protocol厅缺,這樣在 Controller 中使用該 Protocol 提供的方法即可進(jìn)行控制了,代碼如下
.h中:
@protocol BackButtonHandlerProtocol <NSObject>
@optional
// 重寫下面的方法以攔截導(dǎo)航欄返回按鈕點(diǎn)擊事件宴偿,返回 YES 則 pop湘捎,NO 則不 pop
-(BOOL)navigationShouldPopOnBackButton;
@end
@interface UIViewController (BackButtonHandler) <BackButtonHandlerProtocol>
@end
.m中
@implementation UIViewController (BackButtonHandler)
@end
@implementation UINavigationController (ShouldPopOnBackButton)
- (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(navigationShouldPopOnBackButton)]) {
shouldPop = [vc navigationShouldPopOnBackButton];
}
if(shouldPop) {
dispatch_async(dispatch_get_main_queue(), ^{
[self popViewControllerAnimated:YES];
});
} else {
// 取消 pop 后,復(fù)原返回按鈕的狀態(tài)
for(UIView *subview in [navigationBar subviews]) {
if(0. < subview.alpha && subview.alpha < 1.) {
[UIView animateWithDuration:.25 animations:^{
subview.alpha = 1.;
}];
}
}
}
return NO;
}
@end
調(diào)用:
在需要定制的ViewController中導(dǎo)入分類
#import "UIViewController+BackButtonHandler.h"
重寫navigationShouldPopOnBackButton方法:
- (void)navigationShouldPopOnBackButton {
// 定制具體的pop方式
if ([self.inputParameter[@"isAgreementPage"] boolValue]) {
[self.navigationController popToRootViewControllerAnimated:YES];
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
@end