【问题标题】:UINavigationController Broken in IOS 8?UINavigationController 在 IOS 8 中损坏?
【发布时间】:2014-10-16 20:37:01
【问题描述】:

我的应用程序中有一系列 UIViewController,它们使用 UINavigationController 呈现。 HOME ViewController 调用 pushViewController 来访问 PROFILES ViewController。 PROFILES 屏幕正确显示返回到 HOME 的按钮。然后在 PROFILES 上选择一个按钮将用户带到 DETAIL ViewController。 DETAIL 屏幕正确显示 PROFILES 的返回按钮。但是当我按下返回按钮到 PROFILES 时,我确实返回了 PROFILES 屏幕,但是该屏幕上的导航栏现在显示没有返回按钮的标题 HOME。换句话说,IOS 8 似乎已经弹出 ViewController 一次以从 DETAIL 回到 PROFILES,但不知何故弹出了两次导航栏项目!

知道如何解决这个问题吗?

【问题讨论】:

  • 您可能希望包含用于推送到导航堆栈的机制。你用故事板吗?你在使用segues吗?你在使用 pushViewController: 吗?另外,您的日志中是否提到了有关损坏的导航堆栈的任何内容?
  • 我只是在使用旧的标准 pushViewController。我不使用故事板或segues。这确实是基本的 IOS 编码,在旧版本的 IOS 和 XCode 中运行良好,但在使用 XCode 6 的 IOS8 中似乎被破坏了。
  • 您好,您找到解决方案了吗?我有同样的问题
  • 很高兴我不是唯一一个 :-) 请参阅下面的解决方案。

标签: ios objective-c uiviewcontroller uinavigationcontroller ios8


【解决方案1】:

显然解决方案大纲可以在这里找到: UINavigationController and UINavigationBarDelegate.ShouldPopItem() with MonoTouch

在我的解决方案中,我只是让我的所有视图控制器都扩展了 CustomUINavigationController,如下所示:

#import "CustomUINavigationController.h"
#import "IOSVersion.h"

@interface CustomUINavigationController ()

@end

@implementation CustomUINavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.delegate=self;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//
// The following two methods are the key to overriding the buggy behavior in IOS 8
// The first method is from here:
// https://stackoverflow.com/questions/6413595/uinavigationcontroller-and-uinavigationbardelegate-shouldpopitem-with-monotouc
//
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
    NSLog(@"Inside shouldPopItem");
    if (regularPop) {
        NSLog(@"regularPop is TRUE");
    } else {
        NSLog(@"regularPop is FALSE");
    }
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
        if (regularPop) {
            regularPop = FALSE;
            return YES;
        }

        regularPop = TRUE;
        [self popViewControllerAnimated:YES];
        return NO;
    } else {
        return [super navigationBar:navigationBar shouldPopItem:item];
    }
}

- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    NSLog(@"Inside popViewControllerAnimated");
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
        NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.viewControllers];
        int cnt=(int)[viewControllers count];
        NSLog(@"Inside popViewControllerAnimated, cnt is %d",cnt);
        UIViewController *vc=[viewControllers objectAtIndex:cnt-2];
        if (regularPop) self.desiredVC=vc;
        [self popToViewController:vc animated:animated];
        return vc;
    } else {
        return [super popViewControllerAnimated:animated];
    }

}

- (UIViewController *)manualpopViewControllerAnimated:(BOOL)animated {
    NSLog(@"Inside manualpopViewControllerAnimated");
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
        regularPop=TRUE;
        return [self popViewControllerAnimated:animated];
    } else {
        return [super popViewControllerAnimated:animated];
    }
}

- (void)navigationController:(UINavigationController *)navigationController
   didShowViewController:(UIViewController *)viewController
                animated:(BOOL)animated {
    NSLog(@"Inside didShowViewController");
    if (viewController==self.desiredVC) {
        NSLog(@"Inside didShowViewController, found desiredVC");
        regularPop = FALSE;
    }
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

【讨论】:

  • 嗨,Marc,什么是“IOSVersion.h”?那是你的另一个自定义类吗?
  • 是的,这只是我使用的具有 SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0") 之类的宏的文件。您当然可以从名称中推断出它们的作用。例如:#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
猜你喜欢
  • 2014-12-21
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多