1.問題原因:
iOS在根視圖觸發(fā)返回手勢的時候,可能會導(dǎo)致界面卡死,為了解決這個問題,主要的思路就是在根視圖上關(guān)閉返回手勢。
2.解決辦法:
- 創(chuàng)建自定義導(dǎo)航控制器,設(shè)置代理為自己:
- (void)viewDidLoad {
[super viewDidLoad];
@weakiy(self);
self.delegate = weak_self;
}
- 實(shí)現(xiàn)代理方法,在控制器didShow的時候,檢查viewControllers里的元素是否只有一個了。如果只有一個,這個時候就要關(guān)掉返回手勢,否則此時再返回就要觸發(fā)界面卡死的問題了 (重點(diǎn)!!!),
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
NSString * className = NSStringFromClass([navigationController.viewControllers.lastObject class]);
if (navigationController.viewControllers.count == 1)
{
//根視圖控制器關(guān)閉手勢返回
navigationController.interactivePopGestureRecognizer.enabled = NO;
navigationController.interactivePopGestureRecognizer.delegate = nil;
}else
{
//其他的頁面默認(rèn)開啟手勢返回
navigationController.interactivePopGestureRecognizer.enabled = YES;
}
NSLog(@"**************************************1,%@",className);
}
}
3.補(bǔ)充
- 這里有個小技巧值得說一下。通常有些頁面可能會需要關(guān)閉手勢返回,這個時候可以在這里引入一個黑名單的機(jī)制,說白了就是一個數(shù)組,將你想要屏蔽的頁面事先存在這個數(shù)組里,類似下面這樣:
- (NSArray *)blacklist
{
//黑名單中的類禁止手勢返回
if (!_blacklist)
{
_blacklist = @[@"FirstViewController",
@"SecondViewController",
@"ThirdViewController"];
}
return _blacklist;
}
- 然后結(jié)合上面的代理方法,就是這個樣子:
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
NSString * className = NSStringFromClass([navigationController.viewControllers.lastObject class]);
if (navigationController.viewControllers.count == 1)
{
//根視圖控制器關(guān)閉手勢返回
navigationController.interactivePopGestureRecognizer.enabled = NO;
navigationController.interactivePopGestureRecognizer.delegate = nil;
}else if ([self.blacklist containsObject:className])
{
//黑名單中的控制器關(guān)閉手勢返回
navigationController.interactivePopGestureRecognizer.enabled = NO;
navigationController.interactivePopGestureRecognizer.delegate = nil;
}else
{
//其他的頁面默認(rèn)開啟手勢返回
navigationController.interactivePopGestureRecognizer.enabled = YES;
}
NSLog(@"**************************************1,%@",className);
}
}
- 利用NSStringFromClass函數(shù),檢查當(dāng)前出現(xiàn)的頁面是否在黑名單中,將黑名單中的控制器關(guān)閉手勢,這樣就可以在不引入頭文件的情況下實(shí)現(xiàn)宏觀控制單個頁面的側(cè)滑手勢的開關(guān)
4.注意事項(xiàng)
這個方法其實(shí)還是有缺點(diǎn)的,比如將導(dǎo)航控制器的代理設(shè)置成自己了,那么這個時候就不能再變更代理,否則上面這些操作就不會生效。(雖然這些代理方法平時我也不怎么用到)。但是,這里還是給出兩個解決方案吧
- 方案一:將你需要的協(xié)議方法寫成block,在這自定義的導(dǎo)航控制器中實(shí)現(xiàn),再通過block輸出
- 方案二:還是在這自定義的導(dǎo)航控制器中實(shí)現(xiàn)你需要的協(xié)議方法,然后將你在收到協(xié)議方法回調(diào)后需要實(shí)現(xiàn)的方法,暴露到那個控制器的頭文件中,然后在viewControllers中找到那個對象,直接調(diào)他的方法;