美文网首页
扩展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