From 7b02207537d35bfa1714bf8beafc921f717d100a Mon Sep 17 00:00:00 2001 From: 单军华 Date: Wed, 11 Jul 2018 10:47:42 +0800 Subject: [PATCH] 首次上传 --- screendisplay/Pods/FDFullscreenPopGesture/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 227 insertions(+), 0 deletions(-) diff --git a/screendisplay/Pods/FDFullscreenPopGesture/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m b/screendisplay/Pods/FDFullscreenPopGesture/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m new file mode 100755 index 0000000..ac8cb26 --- /dev/null +++ b/screendisplay/Pods/FDFullscreenPopGesture/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m @@ -0,0 +1,227 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 forkingdog ( https://github.com/forkingdog ) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#import "UINavigationController+FDFullscreenPopGesture.h" +#import <objc/runtime.h> + +@interface _FDFullscreenPopGestureRecognizerDelegate : NSObject <UIGestureRecognizerDelegate> + +@property (nonatomic, weak) UINavigationController *navigationController; + +@end + +@implementation _FDFullscreenPopGestureRecognizerDelegate + +- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer +{ + // Ignore when no view controller is pushed into the navigation stack. + if (self.navigationController.viewControllers.count <= 1) { + return NO; + } + + // Disable when the active view controller doesn't allow interactive pop. + UIViewController *topViewController = self.navigationController.viewControllers.lastObject; + if (topViewController.fd_interactivePopDisabled) { + return NO; + } + + // Ignore pan gesture when the navigation controller is currently in transition. + if ([[self.navigationController valueForKey:@"_isTransitioning"] boolValue]) { + return NO; + } + + // Prevent calling the handler when the gesture begins in an opposite direction. + CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view]; + if (translation.x <= 0) { + return NO; + } + + return YES; +} + +@end + +typedef void (^_FDViewControllerWillAppearInjectBlock)(UIViewController *viewController, BOOL animated); + +@interface UIViewController (FDFullscreenPopGesturePrivate) + +@property (nonatomic, copy) _FDViewControllerWillAppearInjectBlock fd_willAppearInjectBlock; + +@end + +@implementation UIViewController (FDFullscreenPopGesturePrivate) + ++ (void)load +{ + Method originalMethod = class_getInstanceMethod(self, @selector(viewWillAppear:)); + Method swizzledMethod = class_getInstanceMethod(self, @selector(fd_viewWillAppear:)); + method_exchangeImplementations(originalMethod, swizzledMethod); +} + +- (void)fd_viewWillAppear:(BOOL)animated +{ + // Forward to primary implementation. + [self fd_viewWillAppear:animated]; + + if (self.fd_willAppearInjectBlock) { + self.fd_willAppearInjectBlock(self, animated); + } +} + +- (_FDViewControllerWillAppearInjectBlock)fd_willAppearInjectBlock +{ + return objc_getAssociatedObject(self, _cmd); +} + +- (void)setFd_willAppearInjectBlock:(_FDViewControllerWillAppearInjectBlock)block +{ + objc_setAssociatedObject(self, @selector(fd_willAppearInjectBlock), block, OBJC_ASSOCIATION_COPY_NONATOMIC); +} + +@end + +@implementation UINavigationController (FDFullscreenPopGesture) + ++ (void)load +{ + // Inject "-pushViewController:animated:" + Method originalMethod = class_getInstanceMethod(self, @selector(pushViewController:animated:)); + Method swizzledMethod = class_getInstanceMethod(self, @selector(fd_pushViewController:animated:)); + method_exchangeImplementations(originalMethod, swizzledMethod); +} + +- (void)fd_pushViewController:(UIViewController *)viewController animated:(BOOL)animated +{ + 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; + } + + // Handle perferred navigation bar appearance. + [self fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController]; + + // Forward to primary implementation. + [self fd_pushViewController:viewController animated:animated]; +} + +- (void)fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:(UIViewController *)appearingViewController +{ + if (!self.fd_viewControllerBasedNavigationBarAppearanceEnabled) { + return; + } + + __weak typeof(self) weakSelf = self; + _FDViewControllerWillAppearInjectBlock block = ^(UIViewController *viewController, BOOL animated) { + __strong typeof(weakSelf) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf setNavigationBarHidden:viewController.fd_prefersNavigationBarHidden animated:animated]; + } + }; + + // Setup will appear inject block to appearing view controller. + // Setup disappearing view controller as well, because not every view controller is added into + // stack by pushing, maybe by "-setViewControllers:". + appearingViewController.fd_willAppearInjectBlock = block; + UIViewController *disappearingViewController = self.viewControllers.lastObject; + if (disappearingViewController && !disappearingViewController.fd_willAppearInjectBlock) { + disappearingViewController.fd_willAppearInjectBlock = block; + } +} + +- (_FDFullscreenPopGestureRecognizerDelegate *)fd_popGestureRecognizerDelegate +{ + _FDFullscreenPopGestureRecognizerDelegate *delegate = objc_getAssociatedObject(self, _cmd); + + if (!delegate) { + delegate = [[_FDFullscreenPopGestureRecognizerDelegate alloc] init]; + delegate.navigationController = self; + + objc_setAssociatedObject(self, _cmd, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return delegate; +} + +- (UIPanGestureRecognizer *)fd_fullscreenPopGestureRecognizer +{ + UIPanGestureRecognizer *panGestureRecognizer = objc_getAssociatedObject(self, _cmd); + + if (!panGestureRecognizer) { + panGestureRecognizer = [[UIPanGestureRecognizer alloc] init]; + panGestureRecognizer.maximumNumberOfTouches = 1; + + objc_setAssociatedObject(self, _cmd, panGestureRecognizer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return panGestureRecognizer; +} + +- (BOOL)fd_viewControllerBasedNavigationBarAppearanceEnabled +{ + NSNumber *number = objc_getAssociatedObject(self, _cmd); + if (number) { + return number.boolValue; + } + self.fd_viewControllerBasedNavigationBarAppearanceEnabled = YES; + return YES; +} + +- (void)setFd_viewControllerBasedNavigationBarAppearanceEnabled:(BOOL)enabled +{ + SEL key = @selector(fd_viewControllerBasedNavigationBarAppearanceEnabled); + objc_setAssociatedObject(self, key, @(enabled), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +@implementation UIViewController (FDFullscreenPopGesture) + +- (BOOL)fd_interactivePopDisabled +{ + return [objc_getAssociatedObject(self, _cmd) boolValue]; +} + +- (void)setFd_interactivePopDisabled:(BOOL)disabled +{ + objc_setAssociatedObject(self, @selector(fd_interactivePopDisabled), @(disabled), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (BOOL)fd_prefersNavigationBarHidden +{ + return [objc_getAssociatedObject(self, _cmd) boolValue]; +} + +- (void)setFd_prefersNavigationBarHidden:(BOOL)hidden +{ + objc_setAssociatedObject(self, @selector(fd_prefersNavigationBarHidden), @(hidden), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end -- Gitblit v1.8.0