Iphone 在旋转之前,“后退”按钮不会出现在导航栏中

Iphone 在旋转之前,“后退”按钮不会出现在导航栏中,iphone,objective-c,ios,cocoa-touch,Iphone,Objective C,Ios,Cocoa Touch,我有三个视图控制器:A->B->C由导航控制器管理A是一个瞬态视图控制器。它向服务器请求一些东西。如果服务器说一切正常,则A将B推到堆栈上B必须隐藏“后退”按钮,因为我不希望用户手动返回到A // B view controller - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.hidesBackButton = YES; self.title = @"B"; } B然

我有三个视图控制器:
A
->
B
->
C
由导航控制器管理<代码>A是一个瞬态视图控制器。它向服务器请求一些东西。如果服务器说一切正常,则
A
B
推到堆栈上
B
必须隐藏“后退”按钮,因为我不希望用户手动返回到
A

// B view controller
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.navigationItem.hidesBackButton = YES;
    self.title = @"B";
}
B
然后,当用户点击表格单元格时,将
C
推到堆栈上

// B view controller
- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    C *c = [[C alloc] 
        initWithStyle:UITableViewStyleGrouped
    ];
    [self.navigationController 
        pushViewController:c 
        animated:YES
    ];
    [c release];
}

如果一切顺利,流程应该如下所示:

-------------    -------------    -------------
|_____A_____|    |_____B ____|    | <B|__ C___|
|           | => |           | => |           |
| loading...|    |   cells   |    |   detail  |
|           |    |           |    |           |
-------------    -------------     -----------
---------------------------
|_____A uuuuuuu124; uuuuuuuuuuub uuuu124; | |=>||
|加载…| |单元| |详图|
|           |    |           |    |           |
-------------    -------------     -----------
由于某些原因,
C
在我旋转设备之前不会显示返回到
B
的后退按钮。旋转后,“后退”按钮将在所有方向上显示。问题似乎源于
B
隐藏后退按钮,然后
C
试图再次显示它,因为如果我不让
B
隐藏它,我就没有这个问题。那么,如何让C显示后退按钮而不强迫用户像猴子一样旋转设备呢

更新
  • 在iOS 4.2.10上的两款不同的Verizon iPhone 4上出现故障
  • AT&T iPhone 3GS在iOS 5.0上运行良好
  • 在iOS 4.3上的AT&T iPhone4上没有问题

我曾经遇到过这个问题,通过给B的导航项一个标题来解决它

// B view controller
- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.navigationItem.hidesBackButton = YES;
    self.navigationItem.title = @"What you want C's back button to say";
    self.title = @"B";
}
如果不希望标题显示在B中,可以将B的navigationItem的标题视图设置为空视图。关于titleView属性:

如果此属性值为nil,则当接收者是顶部项目时,导航项目的标题将显示在导航栏的中心。如果将此属性设置为自定义标题,则将显示该属性而不是标题。如果LeftBarButtonim不是nil,则忽略此属性


我想你需要把你的代码放在C里

-(void)viewDidAppear:(BOOL)animated {
      [super viewDidAppear:animated];
      self.navigationItem.hidesBackButton = NO;
}

尝试放置
self.navigationItem.hidesBackButton=NO编码到init方法或pushViewController调用之前的任何位置

当您第一次向控制器请求视图时,会调用ViewDidLoad,这意味着它可能是从
[self.navigationController pushViewController:c animated:YES]
调用的。但请注意,导航栏不是视图的一部分,它是由
UINavigationController
创建和处理的,因此基本上它可以存在并在调用viewDidLoad和ViewDidDisplay之前绘制。若你们在那个里更新导航栏,它实际上并并没有被重新绘制

编辑1:阅读
[UIViewController navigationItem]

您应该避免将导航项中条形按钮项的创建与视图控制器视图的创建捆绑在一起。可以独立于视图控制器的视图检索视图控制器的导航项。例如,当将两个视图控制器推到导航堆栈上时,最顶部的视图控制器变为可见,但可以检索另一个视图控制器的导航项以显示其后退按钮。要确保已配置导航项,可以覆盖此属性并添加代码以加载其中的条形按钮项,或加载视图控制器初始化代码中的项

编辑2:阅读“我的解决方案不起作用”的评论后再次访问。工作代码(iOS 5,ARC):


编辑3:注意到您主要谈论的是iOS 4.2之后,再次访问。我目前无法在任何iOS 4.2上测试它,但我知道可能的解决方法。您可以始终在UINavigationController中隐藏导航栏,只需在每个屏幕中放置一个单独的导航栏。您将拥有对它们的绝对控制权,甚至可以在Interface Builder中编辑它们。

尝试将其添加到C类:

-(id) init
 {
   [super init];
   self.navigationItem.hidesBackButton = NO;
 }

不确定这是否适用于您的后退按钮情况,但我知道,当我使用自定义后退按钮时,我需要在按下该按钮之前在alloc’d项目上设置自定义后退按钮(与上面的帖子不同)。希望它也能对你的情况起作用——值得一试

换句话说,尝试:

// B view controller
- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    C *c = [[C alloc] 
        initWithStyle:UITableViewStyleGrouped];

    // *** set on c's navigationItem (not self) before you push
    [[c navigationItem] setHidesBackButton: NO];

    [self.navigationController 
        pushViewController:c 
        animated:YES
    ];

    [c release];
}

经过一番搜索后,我在一些老论坛帖子上找到了这个针对iPhone4.2的解决方案(因为你发布了它适用于更高版本)

-(void)viewDidLoad { 
                     [super viewDidLoad];
                     self.navigationItem.hidesBackButton = YES; 
                   }

-(void)viewDidAppear:(BOOL)animated { 
                                       [super viewDidAppear:animated];
                                       self.navigationItem.hidesBackButton = NO; 
                                    }
也许这对你有帮助。
(请查看:)

那么,为什么要在堆栈上保留一个?如果您不想返回到,您可能希望将其从导航控制器中取出。听起来导航栏的绘图例程由于某种原因未被调用,转动设备可能会触发绘图。您可以在设置hideBackButton属性后尝试调用[super viewDidLoad],或者使用[self.navigationController setNavigationBarHidden:false animated:false]在viewDidLoad中重新显示导航栏-这可能会触发绘图,也是。我在堆栈上保留A,因为有时我喜欢跳转到根目录并再次运行A。您也可以在切换到控制器之前尝试在控制器B中显示“后退”按钮C@TheEye我将
self.navigationItem.hidesBackButton=NO
放入
B
视图控制器的
视图将消失
,但它没有解决问题问题,这没用。尽管如此,我还是必须旋转以显示“后退”按钮。按钮会说“B”,而不是“你不想让C的后退按钮说什么”。当导航项不可见且不应该显示时,它会告诉你什么?您还可以查看UINavigationBar的-(void)pushNavigationItem:(UINavigationItem*)项动画:(BOOL)动画方法。这不起作用(在更正拼写错误“viViewDidAppear”后)。不起作用。我把它放在C视图控制器中:
-(id)initWithStyle:(UITableViewStyle)style{self。
// B view controller
- (void)tableView:(UITableView *)tableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    C *c = [[C alloc] 
        initWithStyle:UITableViewStyleGrouped];

    // *** set on c's navigationItem (not self) before you push
    [[c navigationItem] setHidesBackButton: NO];

    [self.navigationController 
        pushViewController:c 
        animated:YES
    ];

    [c release];
}
-(void)viewDidLoad { 
                     [super viewDidLoad];
                     self.navigationItem.hidesBackButton = YES; 
                   }

-(void)viewDidAppear:(BOOL)animated { 
                                       [super viewDidAppear:animated];
                                       self.navigationItem.hidesBackButton = NO; 
                                    }