.h文件
代码块
#define IF(A,B) if(A) {B;}
#define MAKE_SELECTOR(SELECTOR_ONE,SELECTOR_TWO)\
Class class = [self class];\
SEL originalSelector = @selector(SELECTOR_ONE);\
SEL swizzledSelector = @selector(SELECTOR_TWO);\
Method originalMethod = class_getInstanceMethod(class, originalSelector);\
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);\
BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));\
if (success) {\
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));\
} else {\
method_exchangeImplementations(originalMethod, swizzledMethod);\
}
#define DISPATCH(A,B)\
static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{MAKE_SELECTOR(A,B);\
});
#import <UIKit/UIKit.h>
@interface UINavigationController (Kpop)
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *k_Pop_GesRecognizer;
@property (nonatomic, assign) BOOL k_NavBar_Show;
@end
@interface UIViewController (Kpop)
@property (nonatomic, assign) BOOL k_Pop_Disabled;
@property (nonatomic, assign) BOOL k_NavBar_Hidden;
@property (nonatomic, assign) CGFloat k_MaxL_Distance;
@end
.m文件
代码块
#import "UINavigationController+Kpop.h"
#import <objc/runtime.h>
@interface K_Pop_GesDelegate : NSObject <UIGestureRecognizerDelegate>
@property (nonatomic, weak) UINavigationController *nav_VC;
@end
@implementation K_Pop_GesDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer{
UIViewController *topVC = self.nav_VC.viewControllers.lastObject;
IF(self.nav_VC.viewControllers.count <= 1,return NO)
IF(topVC.k_Pop_Disabled,return NO)
CGPoint point_begin = [gestureRecognizer locationInView:gestureRecognizer.view];
CGFloat MAX_Distance = topVC.k_MaxL_Distance;
IF(MAX_Distance > 0 && point_begin.x > MAX_Distance,return NO)
IF([[self.nav_VC valueForKey:@"_isTransitioning"] boolValue],return NO)
CGPoint point_trans = [gestureRecognizer translationInView:gestureRecognizer.view];
IF((point_trans.x <= 0), return NO)
return YES;
}
@end
typedef void (^K_WillAppear_Block)(UIViewController *viewController, BOOL animated);
@interface UIViewController (KPopGes)
@property (nonatomic, copy) K_WillAppear_Block k_WillAppear_block;
@end
@implementation UIViewController (KPopGes)
+ (void)load{
DISPATCH(viewWillAppear:,new_viewWillAppear:)
}
- (void)new_viewWillAppear:(BOOL)animated{
[self new_viewWillAppear:animated];
IF(self.k_WillAppear_block, self.k_WillAppear_block(self, animated))
}
- (K_WillAppear_Block)k_WillAppear_block{
return objc_getAssociatedObject(self, _cmd);
}
-(void)setK_WillAppear_block:(K_WillAppear_Block)block{
objc_setAssociatedObject(self, @selector(k_WillAppear_block), block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end
@implementation UINavigationController (Kpop)
+ (void)load{
DISPATCH(pushViewController:animated:,new_pushViewController:animated:)
}
- (void)new_pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.k_Pop_GesRecognizer]) {
[self.interactivePopGestureRecognizer.view addGestureRecognizer:self.k_Pop_GesRecognizer];
NSArray *arr_Targets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
id firest_target = [arr_Targets.firstObject valueForKey:@"target"];
SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
self.k_Pop_GesRecognizer.delegate = self.k_Pop_Gesdelegate;
[self.k_Pop_GesRecognizer addTarget:firest_target action:internalAction];
self.interactivePopGestureRecognizer.enabled = NO;
}
[self k_setupVC_BasNavBar_IfNeed:viewController];
IF(![self.viewControllers containsObject:viewController], [self new_pushViewController:viewController animated:animated])
}
- (void)k_setupVC_BasNavBar_IfNeed:(UIViewController *)showVC{
IF(!self.k_NavBar_Show, return)
__weak typeof(self) weakSelf = self;
K_WillAppear_Block block = ^(UIViewController *viewController, BOOL animated) {
__strong typeof(weakSelf) strongSelf = weakSelf;
IF(strongSelf, [strongSelf setNavigationBarHidden:viewController.k_NavBar_Hidden animated:animated])
};
showVC.k_WillAppear_block = block;
UIViewController *disappearingVC = self.viewControllers.lastObject;
IF(disappearingVC && !disappearingVC.k_WillAppear_block, disappearingVC.k_WillAppear_block = block)
}
- (K_Pop_GesDelegate *)k_Pop_Gesdelegate{
K_Pop_GesDelegate *delegate = objc_getAssociatedObject(self, _cmd);
if (!delegate) {
delegate = [[K_Pop_GesDelegate alloc] init];
delegate.nav_VC = self;
objc_setAssociatedObject(self, _cmd, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return delegate;
}
- (UIPanGestureRecognizer *)k_Pop_GesRecognizer{
UIPanGestureRecognizer *panGesRec = objc_getAssociatedObject(self, _cmd);
if (!panGesRec) {
panGesRec = [[UIPanGestureRecognizer alloc] init];
panGesRec.maximumNumberOfTouches = 1;
objc_setAssociatedObject(self, _cmd, panGesRec, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return panGesRec;
}
- (BOOL)k_NavBar_Show{
NSNumber *number = objc_getAssociatedObject(self, _cmd);
IF(number, return number.boolValue)
self.k_NavBar_Show = YES;
return YES;
}
- (void)setK_NavBar_Show:(BOOL)enabled{
SEL key = @selector(k_NavBar_Show);
objc_setAssociatedObject(self, key, @(enabled), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
@implementation UIViewController (Kpop)
- (BOOL)k_Pop_Disabled{
return [objc_getAssociatedObject(self, _cmd) boolValue];
}
-(void)setK_Pop_Disabled:(BOOL)disabled{
objc_setAssociatedObject(self, @selector(k_Pop_Disabled), @(disabled), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)k_NavBar_Hidden{
return [objc_getAssociatedObject(self, _cmd) boolValue];
}
-(void)setK_NavBar_Hidden:(BOOL)hidden{
objc_setAssociatedObject(self, @selector(k_NavBar_Hidden), @(hidden), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGFloat)k_MaxL_Distance{
#if CGFLOAT_IS_DOUBLE
return [objc_getAssociatedObject(self, _cmd) doubleValue];
#else
return [objc_getAssociatedObject(self, _cmd) floatValue];
#endif
}
-(void)setK_MaxL_Distance:(CGFloat)distance{
SEL key = @selector(k_MaxL_Distance);
objc_setAssociatedObject(self, key, @(MAX(0, distance)), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
网友评论