如何使用iOS系统自带侧滑返回功能

Demo 展示效果

如何使用iOS系统自带侧滑返回功能_第1张图片
Untitled.gif

从iOS7.0后苹果自带了侧滑返回手势功能interactivePopGestureRecognizer,但是有时我们自定义返回按钮或者隐藏了导航栏,侧滑返回就会失效,而它又是我们的应用使用起来更加人性化必不可少的一部分,如何重现它呢?请往下看~

先看官方介绍


//The gesture recognizer responsible for popping the 
top view controller off the navigation stack. (read-only)
The navigation controller installs this gesture 
recognizer on its view and uses it to pop the topmost 
view controller off the navigation stack. You can use 
this property to retrieve the gesture recognizer and tie 
it to the behavior of other gesture recognizers in your 
user interface. When tying your gesture recognizers 
together, make sure they recognize their gestures 
simultaneously to ensure that your gesture recognizers
 are given a chance to handle the event.

@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

介绍和属性中我们可以知道interactivePopGestureRecognizer是负责把Navigation 栈中最上面的View Controller推出去。而且它只能在iOS7.0及以上可以使用,并且禁止在TVOS中使用!

How to use

  • 由于interactivePopGestureRecognizer是一种手势,因此我们在使用它时需遵循UIGestureRecognizerDelegateProtocol.
    例如:
#import 
@interface ZHRootViewController : UIViewController
@end
  • 我们需要把interactivePopGestureRecognizer使能打开,并设置委托对象,当然在这之前别忘了对系统版本进行判断,因为它只能在iOS7.0及以上使用。
    For example:
- (void)viewDidLoad
{
    [super viewDidLoad];
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;      // 手势有效设置为YES  无效为NO
        self.navigationController.interactivePopGestureRecognizer.delegate = self;    // 手势的代理设置为self
    }
    // Do any additional setup after loading the view.
}
  • 显示或者隐藏NavigationBar 注意这里需要在函数-(void)viewWillAppear:(BOOL)animated 中调用

Like this:

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:animated];//No 为显示Navigationbar Yes 为隐藏
}

做完这些运行后动画效果有了,是不是就完事了呢?No No

  • 你想一想如果已经到Navigation 栈中最底一个Controller时我们还允许侧滑么,显然这时我们应该使侧滑手势失效!

像这样:

-(void)viewDidAppear:(BOOL)animated
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        if (self.navigationController.viewControllers.count==1) {
            self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        }
    }
    
}

或者:

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (self.navigationController.viewControllers.count == 1) {
        return NO;
    }else{
        return YES;
    }
}

到现在我们应该做完了吧? No No

  • 假如我们的View是一个可滑动的View呢?例如ScrollView,TableView,CollectionView。由于它们自带了panGestureRecognizer 所以它们一起使用时可能会产生冲突,如何避免呢?我们可以设置一个手势依赖关系!
    Like this:
 NSArray *gestureArray = self.navigationController.view.gestureRecognizers;//获取所有的手势
    
    //当是侧滑手势的时候设置panGestureRecognizer需要UIScreenEdgePanGestureRecognizer失效才生效即可
    for (UIGestureRecognizer *gesture in gestureArray) {
        if ([gesture isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
            [self.tableView.panGestureRecognizer requireGestureRecognizerToFail:gesture];
        }
    }

这里你也许会疑惑为什么我们上面用的是UIScreenEdgePanGestureRecognizer而不是interactivePopGestureRecognizer

我们先打印self.navigationController.interactivePopGestureRecognizer结果为:

; 
target= <(action=handleNavigationTransition:,
target=<_UINavigationInteractiveTransition 0x7f8283d31600>)>>

打印结果中我们看到了UIScreenEdgePanGestureRecognizer:说明interactivePopGestureRecognizer其实由UIScreenEdgePanGestureRecognizer控制并执行handleNavigationTransition:其代理对象为_UINavigationInteractiveTransition,所以判断中我们使用了UIScreenEdgePanGestureRecognizer.

扩展

我们可以根据UIScreenEdgePanGestureRecognizer,handleNavigationTransition:来自定义我们自己的侧滑返回,这章先讲诉到这里!

Demo

GitHub

今天教师节,祝天下所有教师:节日快乐!

你可能感兴趣的:(如何使用iOS系统自带侧滑返回功能)