美文网首页
扩展FDFullScreenPopGesture支持限制侧滑区域

扩展FDFullScreenPopGesture支持限制侧滑区域

作者: 独孤流 | 来源:发表于2019-08-10 11:32 被阅读0次
    前言

    开发中FDFullscreenPopGesture对开发帮助甚大,很方便解决了导航栏的隐藏显示及全屏侧滑的功能,但是在开发中遇到的一些场景却没法实现,特扩建如下

    1、扩展支持UINavgationController的setViewControllers:animated:方法一次设置多个Controller到UINavgationController时的支持
    UINavigationController+FDFullscreenPopGesture.m

    @implementation UINavigationController (FDFullscreenPopGesture)
    
    + (void)load
    {    
    // Inject "-setViewControllers:animated:"
        Method originalMethod2 = class_getInstanceMethod(self, @selector(setViewControllers:animated:));
        Method swizzledMethod2 = class_getInstanceMethod(self, @selector(fd_setViewControllers:animated:));
        method_exchangeImplementations(originalMethod2, swizzledMethod2);
    }
    - (void)fd_setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
    {
        for(UIViewController *viewController in viewControllers){
            if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.fd_fullscreenPopGestureRecognizer]) {
                
                // Add our own gesture recognizer to where the onboard screen edge pan gesture recognizer is attached to.
                [self.interactivePopGestureRecognizer.view addGestureRecognizer:self.fd_fullscreenPopGestureRecognizer];
                
                // Forward the gesture events to the private handler of the onboard gesture recognizer.
                NSArray *internalTargets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
                id internalTarget = [internalTargets.firstObject valueForKey:@"target"];
                SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
                self.fd_fullscreenPopGestureRecognizer.delegate = self.fd_popGestureRecognizerDelegate;
                [self.fd_fullscreenPopGestureRecognizer addTarget:internalTarget action:internalAction];
                
                // Disable the onboard gesture recognizer.
                self.interactivePopGestureRecognizer.enabled = NO;
            }
            [self fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController];
        }
        [self fd_setViewControllers:viewControllers animated:animated];
    }
    @end
    

    使用一次设置多个Controller到UINavigationController里的demo:

    /**
    * 一次把login、regist都放到NavigationController里,但显示的是register,在register还可以侧滑返回到login页面
    */
    - (void)showRegisterController
    {
        LoginViewController *login = [[LoginViewController alloc]init];
        RegisterViewController *registerVC = [[RegisterViewController alloc] init];
        
        UINavigationController *nav = [[MNavigationController alloc] initWithRootViewController:[UIViewController new]];
    
        [nav setViewControllers:@[login,registerVC] animated:NO];
        UIViewController *appRoot = [UIApplication sharedApplication].keyWindow.rootViewController;
        [appRoot presentViewController: nav animated: YES completion:nil];
    }
    

    2、FDFullscreenPopGesture默认支持的侧滑是全屏都可侧滑,但需求中要求支持距离左侧小部分位置才可侧滑
    UINavigationController+FDFullscreenPopGesture.h

    @interface UIViewController (FDFullscreenPopGesture)
    // 可侧滑交互的距离左侧的位置
    @property (nonatomic, assign) CGFloat fd_interactivePopLeftDistance;
    @end
    

    UINavigationController+FDFullscreenPopGesture.m

    @implementation _FDFullscreenPopGestureRecognizerDelegate
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        UIView *view = gestureRecognizer.view;
        UIViewController *vc =  [[self navigationController:view] childViewControllers].lastObject;
        CGFloat leftDistance = vc.fd_interactivePopLeftDistance;
        CGPoint point = [touch locationInView:view];
        if(leftDistance>0 && point.x > leftDistance){
            return NO;
        }
        return YES;
    }
    - (UINavigationController *)navigationController:(UIView *)view {
    
        UIResponder *responsder = view.nextResponder;
        while (![responsder isKindOfClass:[UINavigationController class]]) {
            view = view.superview;
            responsder = view.nextResponder;
        }
        if([responsder isKindOfClass:[UINavigationController class]]){
            return (UINavigationController *)responsder;
        }else{
            return nil;
        }
    }
    @end
    @implementation UIViewController (FDFullscreenPopGesture)
    // 可侧滑交互的距离左侧的位置
    - (CGFloat)fd_interactivePopLeftDistance
    {
        return [objc_getAssociatedObject(self, _cmd) floatValue];
    }
    - (void)setFd_interactivePopLeftDistance:(CGFloat)fd_interactivePopLeftDistance
    {
        objc_setAssociatedObject(self, @selector(fd_interactivePopLeftDistance), @(fd_interactivePopLeftDistance), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    @end
    

    使用限制侧滑区域demo:

    #import "UINavigationController+FDFullscreenPopGesture.h"
    @interface TestViewController ()
    @end
    @implementation TestViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
       // 设置只在侧滑屏幕左侧100范围内才可以响应侧滑
        self.fd_interactivePopLeftDistance = 100;
    }
    @end
    

    完整代码如下:
    GitHub:FDFullscreenPopGesture

    相关文章

      网友评论

          本文标题:扩展FDFullScreenPopGesture支持限制侧滑区域

          本文链接:https://www.haomeiwen.com/subject/xcoljctx.html