前言
开发中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
网友评论