如果同时触发滑动手势和后退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,直到刷卡完成。