UINavigationController:隐藏一个视图的后退按钮会使所有视图的后退按钮都被隐藏

12

我有一个包含3个 UIViewController 的 UINavigationController 堆栈。

View A - is the root
View B - is pushed by View A and has `self.navigationItem.hidesBackButton = YES;`
View C - is pushed by View B and has `self.navigationItem.hidesBackButton = NO;`

尽管我将hidesBackButton设置为NO,但视图C仍未显示返回按钮。我该如何解决?


请问B视图的标题是什么? - Madhup Singh Yadav
视图B - self.title = @"优惠" - Sheehan Alam
你应该尝试向苹果提交一个错误报告,或者直接给他们发送一封邮件请求支持。 - Madhup Singh Yadav
8个回答

15

更新
在4.2版本中可能存在一个bug,但是在4.1版本的sdk中它是正常工作的。

我已经尝试过这个方法,我的代码可以完美地运行。我只是发布了B视图控制器(BVC)和C视图控制器(CVC)的实现。我的初步猜测是你没有在viewDidLoad中设置BVC的标题。

@implementation BVC


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = @"I am B";
}


- (void) viewWillAppear:(BOOL)animated{
    self.navigationItem.hidesBackButton = YES;
}

- (IBAction)pushB:(UIButton *)sender{
    CVC *cvc = [[CVC alloc] initWithNibName:@"CVC" bundle:nil];
    [self.navigationController pushViewController:cvc animated:YES];
    [cvc release];
}
@end

@implementation CVC

- (void) viewWillAppear:(BOOL)animated{
    self.navigationItem.hidesBackButton = NO;
}
@end

+1,它帮了我很多。但实际上我需要在所有视图中隐藏它,但我无法做到。我已经在每个视图中写了这个 :( - mAc

7

我认为您需要在推送或弹出视图控制器之前设置该属性,以影响下一个视图控制器,在viewWillAppear中设置当前视图控制器为时已经太迟了。

编辑:这看起来像是4.2版本的一个错误!在4.2模拟器和设备上隐藏返回按钮仍然存在问题,但在3.2、4.1和4.0模拟器上可以正常工作!

以下是当使用隐藏的返回按钮推送VC时的代码:

- (IBAction) goto2nd
{
    SecondVC *vc = [[[SecondVC alloc] initWithNibName:@"SecondVC" bundle:nil] autorelease];
    vc.navigationItem.hidesBackButton = YES;
    [self.navigationController pushViewController:vc animated:YES];
}

这就是所需的全部内容,每个视图控制器都有自己的navigationItem,它不是一个全局设置,因此您无需取消它以恢复返回按钮(至少在弹回到设置为“NO”的VC时)。


仍然没有成功。尝试在推出视图B之前设置viewB.navigationItem.hidesBackButton = YES,并在推出视图C之前设置viewC.navigationItem.hidesBackButton = NO,但是没有成功。 - Sheehan Alam
好的,我看到了同样的事情 - 很奇怪,正在调查中。 - Bogatyr
我确认这个 bug。4.2 版本隐藏了返回按钮,但我的 4.0 设备正常显示。 - gonso

6

以下是我在4.3上成功使用的解决方法。

不要隐藏返回按钮,而是将左侧栏按钮视图设置为一个空视图:

UIView *tmpView = [[UIView alloc] initWithFrame:CGRectZero];
UIBarButtonItem *tmpButtonItem = [[UIBarButtonItem alloc] initWithCustomView:tmpView];
[tmpView release];
self.navigationItem.leftBarButtonItem = tmpButtonItem;
[tmpButtonItem release];

为了恢复返回按钮,只需将左侧栏按钮项设置为nil:
[self.navigationItem setLeftBarButtonItem:nil animated:YES];

更新:看起来 4.3 版本中已经修复了这个 bug。

注意:尽管这个 bug 已经被修复,我仍然更喜欢使用“空视图”技术,因为它允许后退按钮的消失和出现动画化。


这种方法完全移除了[<返回]按钮,而navigationItem.hidesBackButton仅隐藏箭头并禁用剩余文本。 - HBublitz

1
这个问题的解决方案有点棘手...只需尝试一下,它肯定会起作用,因为我也遇到了同样的问题。
首先在viewWillAppear中设置导航标题。
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.navigationItem.title = @"SET YOUR TITLE";
}

当您导航到其他页面时,只需将导航标题设置为null。这将不会在顶部显示任何按钮。因为您可以摆脱每次编写self.navigationItem.hidesBackButton = YES;的麻烦。

- (IBAction)pushB:(UIButton *)sender
{
    SecondVC *vc = [[[SecondVC alloc] initWithNibName:@"SecondVC" bundle:nil] autorelease];
    self.navigationItem.title = @"";
    [self.navigationController pushViewController:vc animated:YES];
    [vc release];
}

0

我遇到了同样的问题,而且只在iOS 4.2模拟器上出现,所以很可能是那个版本的一个bug。

更新:

尝试使用这个方法,对我有用:

- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];
    self.navigationItem.hidesBackButton = NO;
}

0
使用UINavigationControllerDelegate方法-navigationController:willShowViewController:animated:。您将在视图控制器A和视图控制器B中实现此方法。在A中,您将设置-hidesBackButton:YES,而在视图控制器B中则设置为NO
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    viewController.hidesBackButton = YES;
}

0

您也可以使用以下示例代码:

- (void) viewWillAppear:(BOOL)animated{
    self.navigationItem.hidesBackButton = YES;
}

- (void) viewWillDisappear:(BOOL)animated{
    self.navigationItem.hidesBackButton = NO;
}

0
如果您的视图层次结构确实是这样的,即View B不应该显示返回按钮,但View C应该,则绕过此问题的最简单方法是重构您的层次结构。我正在考虑以下替代方案:
视图A在View B*上调用 presentModalViewController:animated: ,View B *是 UINavigationController ,其 view 属性是View B。 View B*响应于来自View B的事件(或其他信息)将View C推送到其导航堆栈中。如果您需要快速跳回View A,请在View A上调用 dismissModalViewControllerAnimated:。如果要在内存中保留View B *和C的状态,则还可以在某个地方保留对View B *的另一个指针,以便在解散时不会消失。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接