如果同时触发滑动手势和后退按钮,导航栏会变得很时髦
Posted
技术标签:
【中文标题】如果同时触发滑动手势和后退按钮,导航栏会变得很时髦【英文标题】:Navigation Bar gets funky if Swipe Gesture and Back Button are triggered at the same time 【发布时间】:2015-01-09 00:42:23 【问题描述】:今天我们的一位测试人员向我展示了,如果他在向后滑动的同时按下导航栏的后退按钮,会产生一个非常有趣的导航栏行为:
如果我们在第三个视图控制器上执行此操作而不是返回顶部,然后再次进入一层并单击后退按钮,大多数情况下导航栏不会消失,或者可能不会动画。或者不出现在更深层次。或者虽然不在顶视图控制器中,但停用后退按钮。
有时此消息会打印到控制台:
在意外状态下完成导航转换。导航栏子视图树可能已损坏。
事实证明它必须在 Apples 类中,因为我能够用普通类重现它。代码在GitHub。您必须在手机上运行该应用程序才能同时执行手势和按钮点击。
我还准备了video。
我该如何解决?
【问题讨论】:
为什么投反对票?这是一个很好的问题,我自己也有同样的问题。我的答案如下。 @MikeTaverne,我怀疑否决票与问题有关。有些人不喜欢“危险风格”的问答,即使在常见问题解答和用户界面中鼓励这样做。其他反对票是报复票。 【参考方案1】:为了解决这个问题,我禁用了导航栏的用户交互。为此,我将 UINavigationViewController 子类化并使用 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 上找到固定代码。
【讨论】:
【参考方案2】:假设您有一个带有视图控制器 A --> B --> C 的导航控制器。
当您在 C 上,滑回 B,然后在抬起滑动手指之前触摸 B 上的返回按钮时,会出现问题。
为了防止这种情况:
在 B 视图中DidDisappear:
navigationItem.hidesBackButton = true
在 B viewDidAppear 中:
navigationItem.hidesBackButton = false
这具有防止触摸 B 的后退按钮直到滑动完成的效果。
【讨论】:
不管怎样,Apple 自己的应用程序无法处理这种情况。例如,可以在邮件和设置应用程序中轻松重现该错误。以上是关于如果同时触发滑动手势和后退按钮,导航栏会变得很时髦的主要内容,如果未能解决你的问题,请参考以下文章