interactivePopGestureRecognizer

介绍了iOS7中加入的右滑返回功能,并提供了当自定义返回按钮时如何保持该手势功能的方法。

苹果一直都在人机交互中尽力做到极致,在iOS7中,新增加了一个小小的功能,也就是这个api:self.navigationController.interactivePopGestureRecognizer.enabled = YES;

这个api功能就是在NavigationController堆栈内的UIViewController可以支持右滑手势,也就是不用点击右上角的返回按钮,轻轻在屏幕左边一

滑,屏幕就会返回,随着ios设备屏幕的增大,这个小功能让手指短,拇指大和手残人士看到了福音。

这个功能是好,但是经常我们会有需求定制返回按钮,如果手动定制了返回按钮,这个功能将会失效,也就是自定义了navigationItem的leftBarButtonItem,那么这个手势就会失效。解决方法找到两种 

 1.重新设置手势的delegate

 self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;

 2.当然你也可以自己响应这个手势的事件

 [self.navigationController.interactivePopGestureRecognizer addTarget:self action:@selector(handleGesture:)];

有更多方法以后继续补充,这里可以根据自己需要进行选择,如果只是简单定制了返回按钮,第一种最简单,一句代码搞定。

override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if isFromClickNotification { self.tpNavigationController?.interactivePopGestureRecognizer?.isEnabled = false let screenGesture = UIScreenEdgePanGestureRecognizer.init(target: self, action: #selector(handleEdgeLeftGesture)) screenGesture.delegate = self screenGesture.edges = UIRectEdge.left self.view.addGestureRecognizer(screenGesture) } mediaPlayerWindowViewController.setPlaybackType(Int(TPSS_MP_PLAYBACK_TYPE_MSG_PLAYBACK)) if isFirst { isFirst = false } else { // mediaPlayerWindowViewController.upgradeForegroundWindows(false, false, calendar.date(from: playbackTime as DateComponents)!.timeIntervalSince1970) self.changeMessagePlayingIndex(from: IndexPath.init(row: currentMessageIndex, section: 0)) flowWindowView.setFlowLabel(speed: 0, content: mediaPlayerWindowViewController.getDataRecevied()) } if isCloudVMS || isLocalVms { if(currentMessageIndex < siteMessageArray.count){ self._collectionView?.scrollToItem(at: IndexPath.init(row: currentMessageIndex, section: 0), at: .centeredVertically, animated: true) } } else { if(currentMessageIndex < viewModel.rowCountForSections[0]){ self._collectionView?.scrollToItem(at: IndexPath.init(row: currentMessageIndex, section: 0), at: .centeredVertically, animated: true) } } //更新播放倍速 self.updatePlaySpeed(numerator: speedNumerator, denominator: speedDenominator) DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) { self.showVisibleAreaCells() if self.appContext.isVmsLogin { self.preconnectToRelay(devId: self.windowConfig?.identifier ?? self.device.identifier, siteId: Int64(self.currentVmsMessage?.siteID ?? 0), channelId: self.windowConfig?.channelId ?? -1, isPreview: false) } } }
10-15
#import "TPNavigationController.h" #import "TPContainerViewController.h" #import "TPContainerNavigationController.h" #import "UIViewController+TPNavigationExtension.h" #import <TPFoundation/TPUIUtils.h> @implementation TPContainerNavigationController + (instancetype)wrapNavigationControllerWithViewController:(UIViewController *)viewController { return [[self alloc] initWithViewController:viewController]; } - (instancetype)initWithViewController:(UIViewController *)viewController { if (self = [super init]) { self.viewControllers = @[viewController]; } return self; } - (void)viewDidLoad { [super viewDidLoad]; // 禁用包装的vc的返回手势 self.interactivePopGestureRecognizer.enabled = NO; } - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { TPContainerViewController *fromContainer = (TPContainerViewController *)self.navigationController.topViewController; if (![self shouldKeepOrientationFromController:[fromContainer rootViewController] toController:viewController]) { [self ensureOrientationIsPortrait]; } // push一个包装后的控制器 TPContainerViewController *wrapViewController = [TPContainerViewController wrapViewController:viewController]; if (self.tpNavigationController.viewControllers.count >= 1) { if (@available(iOS 9.0, *)) { wrapViewController.hidesBottomBarWhenPushed = YES; viewController.hidesBottomBarWhenPushed = YES; } else { // for iOS 8, set tabbar hidden [[self tabBarController].tabBar setHidden:YES]; } } //使用Xcode12.0.1编译的App,在iOS14上运行时,当调用popToRootViewControllerAnimated:YES到vc栈中非相邻的vc时,会发现rootViewController的tabbar消失了,如果是popToRootViewControllerAnimated:NO则没问题 // 应该是官方的bug,先复写该方法解决 else { if (@available(iOS 14.0, *)) { viewController.hidesBottomBarWhenPushed = NO; } } [self.navigationController pushViewController:wrapViewController animated:animated]; } - (UIViewController *)popViewControllerAnimated:(BOOL)animated { NSInteger controllersCount = self.navigationController.viewControllers.count; if (controllersCount > 1) { TPContainerViewController *fromContainer = (TPContainerViewController *)self.navigationController.topViewController; TPContainerViewController *toContainer = self.navigationController.viewControllers[controllersCount - 2]; if (![self shouldKeepOrientationFromController:[fromContainer rootViewController] toController:[toContainer rootViewController]]) { [self ensureOrientationIsPortrait]; } } if (self.navigationController) { return [self.navigationController popViewControllerAnimated:animated]; } return [super popViewControllerAnimated:animated]; } - (NSArray<UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated { [self ensureOrientationIsPortrait]; return [self.navigationController popToRootViewControllerAnimated:animated]; } - (NSArray<UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated { [self ensureOrientationIsPortrait]; TPNavigationController *tpNavigationController = viewController.tpNavigationController; // pop到指定vc时应找到对应的tpContainerViewController NSInteger index = [tpNavigationController.tpChildViewControllers indexOfObject:viewController]; return [self.navigationController popToViewController:tpNavigationController.viewControllers[index] animated:animated]; } - (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { [self ensureOrientationIsPortrait]; [self.navigationController presentViewController:viewControllerToPresent animated:flag completion:completion]; } - (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion { [self ensureOrientationIsPortrait]; [self.navigationController dismissViewControllerAnimated:flag completion:completion]; } - (void)setDelegate:(id<UINavigationControllerDelegate>)delegate { self.navigationController.delegate = delegate; } - (void)ensureOrientationIsPortrait { if (UIInterfaceOrientationIsPortrait([TPUIUtils getScreenOrientation])) { return; } if (@available(iOS 16.0, *)) { [self setNeedsUpdateOfSupportedInterfaceOrientations]; } [TPUIUtils changeScreenOrientationTo:UIInterfaceOrientationPortrait]; } - (BOOL)shouldKeepOrientationFromController:(UIViewController *)fromController toController:(UIViewController *)toController { SEL selector = @selector(controllersNeedToKeepOrientationWhenNavigating); if ([fromController respondsToSelector:selector]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" NSArray *controllers = [fromController performSelector:selector]; #pragma clang diagnostic pop NSString *toControllerName = NSStringFromClass([toController class]); if ([controllers containsObject:toControllerName]) { return YES; } } return NO; } @end
09-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值