如果同时触发滑动手势和后退button,则导航栏会变得时髦

今天我们的一个testing人员告诉我,如果他按下导航栏的后退button的同时向后滑动,则会在导航栏中创build一个非常有趣的行为:

如果我们在第三个视图控制器上,并执行此操作比返回顶部,再次进入一个级别,并在大多数情况下单击后退button导航栏不会消失,如果它应该,或者它可能不会animation。 或者不在更深层次上出现。 或者取消激活后退button,尽pipe不在顶部视图控制器中。

有时这些消息被打印到控制台:

完成处于意外状态的导航转换。 导航栏子视图树可能会损坏。

事实certificate,它必须在苹果类,因为我能够用简单的课程重现它。 代码在GitHub上 。 您将不得不在手机上运行应用程序来一次执行手势和button点击。

在这里输入图像说明

我也准备了一个video 。

我如何解决它?

要解决这个问题,我禁用导航栏的用户交互。 为此,我inheritanceUINavigationViewController并使用Key-Value-Observing检测手势识别器的状态。

#import "NavigationViewController.h" @interface NavigationViewController () @end @implementation NavigationViewController - (void)viewDidLoad { [super viewDidLoad]; [self.interactivePopGestureRecognizer addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqual:@"state"]) { [self recognizer:object changedState:[change[@"new"] integerValue] oldState:[change[@"old"] integerValue]]; } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } - (void)recognizer:(UIGestureRecognizer *)recognizer changedState:(UIGestureRecognizerState)newState oldState:(UIGestureRecognizerState)oldState { switch (newState) { case UIGestureRecognizerStateEnded: case UIGestureRecognizerStateCancelled: case UIGestureRecognizerStateFailed: [self.navigationBar setUserInteractionEnabled:YES]; break; case UIGestureRecognizerStateBegan: [self.navigationBar setUserInteractionEnabled:NO]; break; default: break; } } - (void)dealloc { [self.interactivePopGestureRecognizer removeObserver:self forKeyPath:@"state"]; } @end 

您将在GitHub上find固定的代码。

假设你有一个带有视图控制器A – > B – > C的导航控制器。

当您在C上时,出现问题,滑回到B,然后触摸B上的“后退”button,然后抬起您的手指。

为了防止这一点:

在B viewDidDisappear中:

  navigationItem.hidesBackButton = true 

在B viewDidAppear:

  navigationItem.hidesBackButton = false 

这有防止触摸B的后退button,直到刷卡完成。