UINavigationController+SXFullScreen.m 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //
  2. // UINavigationController+SXFullScreen.m
  3. // UINavigation-SXFixSpace
  4. //
  5. // Created by charles on 2017/9/8.
  6. // Copyright © 2017年 None. All rights reserved.
  7. //
  8. #import "UINavigationController+SXFullScreen.h"
  9. #import "NSObject+SXRuntime.h"
  10. @implementation UIViewController (SXFullScreen)
  11. -(BOOL)sx_disableInteractivePop{
  12. return [objc_getAssociatedObject(self, @selector(sx_disableInteractivePop)) boolValue];
  13. }
  14. -(void)setSx_disableInteractivePop:(BOOL)sx_disableInteractivePop{
  15. objc_setAssociatedObject(self, @selector(sx_disableInteractivePop), @(sx_disableInteractivePop), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  16. }
  17. @end
  18. @interface UINavigationController()<UIGestureRecognizerDelegate>
  19. @end
  20. @implementation UINavigationController (SXFullScreen)
  21. + (void)load {
  22. static dispatch_once_t onceToken;
  23. dispatch_once(&onceToken, ^{
  24. [self swizzleInstanceMethodWithOriginSel:@selector(viewDidLoad)
  25. swizzledSel:@selector(sx_viewDidLoad)];
  26. });
  27. }
  28. -(void)sx_viewDidLoad {
  29. //接替系统滑动返回手势
  30. NSArray *internalTargets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
  31. id internalTarget = [internalTargets.firstObject valueForKey:@"target"];
  32. SEL handler = NSSelectorFromString(@"handleNavigationTransition:");
  33. UIPanGestureRecognizer * fullScreenGesture = [[UIPanGestureRecognizer alloc]initWithTarget:internalTarget action:handler];
  34. fullScreenGesture.delegate = self;
  35. fullScreenGesture.maximumNumberOfTouches = 1;
  36. UIView *targetView = self.interactivePopGestureRecognizer.view;
  37. [targetView addGestureRecognizer:fullScreenGesture];
  38. [self.interactivePopGestureRecognizer setEnabled:NO];
  39. [self sx_viewDidLoad];
  40. }
  41. /**
  42. 全屏滑动返回判断
  43. @param gestureRecognizer 手势
  44. @return 是否响应
  45. */
  46. - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer {
  47. if (self.topViewController.sx_disableInteractivePop) {
  48. return NO;
  49. }
  50. if ([gestureRecognizer translationInView:gestureRecognizer.view].x <= 0) {
  51. return NO;
  52. }
  53. if ([[self valueForKey:@"_isTransitioning"] boolValue]) {
  54. return NO;
  55. }
  56. return (self.childViewControllers.count != 1);
  57. }
  58. //修复有水平方向滚动的ScrollView时边缘返回手势失效的问题
  59. -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
  60. return (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && [otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]);
  61. }
  62. @end