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

时间:2015-01-09 00:42:23

标签: ios objective-c cocoa-touch uinavigationbar

今天我们的一位测试人员告诉我,如果他在向后滑动时按下导航栏的后退按钮会导致导航栏的一个非常有趣的行为:

如果我们在第三个视图控制器并且执行此操作而不是返回到顶部,那么再次进入一个级别并在大多数情况下单击后退按钮,导航栏将不会消失,如果它应该,或者它可能不会动画。或者不会出现在更深层次。或者取消激活后退按钮,但不在顶视图控制器中。

有时会将此消息打印到控制台:

  

在意外状态下完成导航转换。导航栏子视图树可能已损坏。

事实证明它必须在Apples类中,因为我能够使用普通类重现它。代码位于GitHub。您必须在手机上运行应用程序才能立即执行手势和按钮点击。

enter image description here

我还准备了video

我该如何解决?

2 个答案:

答案 0 :(得分:2)

要解决此问题,我会禁用导航栏的用户互动。为此,我将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上找到固定代码。

答案 1 :(得分:1)

假设您有一个带有视图控制器A的导航控制器 - > B - >下进行。

当你在C上,向后滑动到B,然后触摸B上的后退按钮,然后抬起你的滑动手指,就会出现问题。

为了防止这种情况:

在B viewDidDisappear中:

    navigationItem.hidesBackButton = true

在B viewDidAppear中:

    navigationItem.hidesBackButton = false

这样可以防止触摸B&#39后退按钮,直到滑动完成。