UINavigationController: Скрытие кнопки на одном экране скрывает ее для всех просмотров

У меня есть UINavigationController, который содержит 3 UIViewControllers в стеке.

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;`

В режиме просмотра C не отображается кнопка "Назад", даже если у меня есть hidesBackButton, установленного в NO. Как я могу это решить?

Ответ 1

Обновление
Возможная ошибка в 4.2, поскольку она работает до 4.1 sdks

Я пробовал это, и мой работает отлично. Я просто размещаю реализацию контроллера B view (BVC) и C view controller (CVC). Моя первоначальная догадка заключается в том, что вы не устанавливаете заголовок BVC в viewDidLoad.

@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

Ответ 2

Я думаю, вам нужно установить это свойство, прежде чем вы нажмете или поместите контроллер представления, чтобы повлиять на следующий контроллер представления, установив его для текущего контроллера представления в viewWillAppear слишком поздно.

Изменить: это выглядит как ошибка в 4.2! Кнопка "Назад" остается скрытой как в симуляторе 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];
}

Это все, что должно быть необходимо, каждый VC имеет свой собственный параметр navigationItem, это не глобальная настройка, поэтому вам не нужно беспокоить его отмену, чтобы восстановить кнопку возврата (по крайней мере, когда вы возвращаетесь обратно в VC, где он установлен на "NO" ).

Ответ 3

Вот обходной путь, который я успешно использую в 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.

Примечание. Несмотря на то, что ошибка кажется исправленной, я предпочитаю метод "пустой вид", потому что он позволяет анимировать исчезновение и повторное появление кнопки "Назад" .

Ответ 4

Решение этой проблемы несколько сложно. Просто попробуйте, она будет работать, так как даже я столкнулся с той же проблемой.

Сначала установите заголовок навигации в 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];
}

Ответ 5

Когда вы вернетесь (однако вы это делаете), reset свойство hidesBackButton на YES. Например, в вашем методе viewWillAppear: сделайте что-то вроде

@implementation SomeViewController

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

@end

Я полагаю, это было бы так просто, но я мог ошибаться. В конце концов, элемент навигации принадлежит UINavigationController, поэтому имеет смысл, что внесенные в него изменения не будут сохранены/восстановлены в зависимости от того, какой UIViewController находится в стеке UINavigationController.

Ответ 6

У меня такая же проблема, и это происходит только на симуляторе iOS 4.2, поэтому, вероятно, это ошибка в этой версии.

Пересоздать:

Попробуй с этим, это сработало для меня:

- (void)viewDidAppear:(BOOL)animated {

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

Ответ 7

Используйте метод UINavigationControllerDelegate -navigationController:willShowViewController:animated:. Вы реализуете это в виде контроллера A и контроллера B. В A вы установите -hidesBackButton: в YES и, альтернативно, в NO в контроллере B. B./

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    viewController.hidesBackButton = YES;
}

Ответ 8

Вы также можете использовать следующий пример кода:

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

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

Ответ 9

Если ваш взгляд на иерархию на самом деле таков, что View B не должен показывать кнопку "Назад", но View C должен, то самый простой способ обойти это - реорганизовать вашу иерархию. Я думаю о следующей альтернативе:

View A вызывает presentModalViewController:animated: в представлении B *, a UINavigationController, чье свойство view - это вид B. View B * нажимает View C на свой стек навигации в ответ на событие (или иначе) из View B. Если вам нужно вернуться к Быстрый просмотр, затем вызов dismissModalViewControllerAnimated: в виде A. Если вы хотите сохранить состояние View B * и C в памяти, вы также можете сохранить другой указатель на View B * где-нибудь, чтобы он не уходил, когда его отклонили.