Скрыть панель навигации, но когда я перехожу в предыдущий (всплывающий) вид, он временно показывает старую кнопку «Назад». Почему?

У меня есть контроллеры представления в контроллере навигации (root: RootViewController, second: ReadingViewController), но во втором контроллере представления я хочу отключить панель навигации для UIToolBar (поскольку мне не нужен заголовок и мне нужно больше кнопок, как в iBooks или приложение Facebook). Проблема в том, что когда я скрываю панель навигации во втором представлении, она снова появляется случайным образом на секунду, когда я открываю контроллер представления (возвращаюсь).

Когда я открываю контроллер представления, на секунду появляется кнопка возврата:

введите описание изображения здесь

Во втором контроллере представления я скрываю панель навигации в viewWillAppear::

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self.navigationController setNavigationBarHidden:YES animated:YES];
}

Также во втором контроллере представления я восстанавливаю панель навигации в viewWillDisappear::

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    // ... other stuff

    [self.navigationController setNavigationBarHidden:NO animated:YES];
}

Мне интересно, как я борюсь с этой проблемой, чтобы контроллеры представления переходили плавно.


person Doug Smith    schedule 28.04.2013    source источник
comment
Покажите код, имена контроллера представления и т. Д. Что вы на самом деле делаете?   -  person matt    schedule 29.04.2013
comment
Добавлено: если я что-то пропустил, просто спросите.   -  person Doug Smith    schedule 01.05.2013
comment
Я не могу воспроизвести проблему. Смотри, я сделал тебе видео! youtu.be/PxpchytWQ4A Для меня это настолько логично, насколько вы собираетесь показывать и скрывать панель навигации. когда вы толкаете и хлопаете.   -  person matt    schedule 01.05.2013
comment
Не могли бы вы поделиться своим проектом?   -  person Doug Smith    schedule 01.05.2013
comment
Отредактируйте мой ответ, чтобы показать код, который я использовал. Довольно просто. Но на самом деле я подозреваю, что проблема здесь в том, что вы делаете что-то еще, которое не описываете. В таких случаях нужно создать минимальный проект, который концентрируется только на решаемой проблеме (как это сделал я). Таким образом вы убедитесь, что это может работать. Тогда вы можете беспокоиться о том, что еще вы делаете, что мешает его работе.   -  person matt    schedule 01.05.2013
comment
Из любопытства, думали ли вы о том, чтобы оставить панель навигации на месте и использовать новые API [UINavigationItem leftBarButtonItems] и [UINavigationItem rightBarButtonItems]?   -  person Ell Neal    schedule 06.05.2013
comment
В первом представлении контроллера viewWillAppear попробуйте установить [self.navigationController setNavigationBarHidden: NO animated: NO];   -  person Xcoder    schedule 07.05.2013
comment
@DougSmith Проверьте ответ, который я опубликовал.   -  person Ayush    schedule 21.05.2013


Ответы (8)


Эй, почему бы тебе не использовать панель навигации как UIToolbar.

Вместо того, чтобы скрывать UINavigation, вы можете имитировать контроллер навигации для UITootlbar, добавляя к нему кнопки.

сокрытие показа UINavigation было бы сложной задачей.

Я загрузил ссылку в Dropbox.

person Ayush    schedule 20.05.2013
comment
Это интересная идея, и я бы постарался сделать это именно так. Вместо использования leftBarButtonItem попробуйте использовать leftBarButtonItems (обратите внимание на «s» в конце, это массив элементов). Таким образом, вы можете иметь столько элементов на панели навигации, сколько захотите. Вы можете увидеть пример использования в Pages.app. - person Tricertops; 24.05.2013

Проблема в том, что viewDidLoad слишком рано! Помните, что viewDidLoad не имеет ничего общего с интерфейсом и самой анимацией push. Это не означает, что представление этого контроллера представления вот-вот появится на экране! Это просто означает, что контроллер представления получил свое представление.

Я сделал видео, показывающее, что происходит на моем компьютере, когда я перемещаюсь между двумя контроллерами представления в интерфейсе навигации, один из которых показывает панель навигации, а другой нет: http://youtu.be/PxpchytWQ4A

Для меня это настолько логично, насколько вы собираетесь показывать и скрывать панель навигации, когда вы нажимаете и хлопаете! Вот код, который я использовал. Контроллер представления, который скрывает свою панель навигации, относится к классу ViewController2. Этот код находится в делегате приложения:

- (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    dispatch_async(dispatch_get_main_queue(), ^{
        [(UINavigationController*)self.window.rootViewController setDelegate:self];
    });
    return YES;
}

-(void)navigationController:(UINavigationController *)nc 
     willShowViewController:(UIViewController *)vc 
                   animated:(BOOL)animated 
{
    [nc setNavigationBarHidden:([vc isKindOfClass:[ViewController2 class]]) 
                      animated:animated];   
}

Это все, что я сделал.

person matt    schedule 28.04.2013
comment
Если я сделаю это в viewWillAppear, он будет там на секунду, будет удален, а затем UIToolBar упадет, когда он будет удален. - person Doug Smith; 29.04.2013
comment
Может попробовать viewDidAppear. Я заметил, что вы все еще не показали кода, как я просил. Это полная глупость и догадки, если вы на самом деле не показываете, что именно вы делаете. - person matt; 29.04.2013
comment
Это не сработало в viewDidAppear, но я добавил то, что вы просили, и если я что-то пропустил, просто скажите. - person Doug Smith; 01.05.2013
comment
Я изменил свой ответ, чтобы дать решение, которое работает для меня. Я не знаю, почему ваш код не работает для вас. - person matt; 01.05.2013
comment
Могу ли я что-нибудь делать в своей раскадровке? - person Doug Smith; 01.05.2013
comment
Как я должен знать? В моем проекте используется раскадровка, и я не вижу проблемы. Поскольку я не могу воспроизвести вашу проблему, я ничем не могу помочь. Но я действительно думаю, что доказал, что какой бы сбой вы ни наблюдали, он не должен происходить, когда панель навигации отображается и скрывается во время перехода push / pop. - person matt; 01.05.2013
comment
Я нашел это, есть элемент навигации назад, который я не могу удалить: i.imgur.com/MAa2kHA.png - person Doug Smith; 05.05.2013
comment
Задний элемент принадлежит предыдущему контроллеру представления. - person matt; 06.05.2013
comment
Не скрывайте панель навигации с анимацией, думаю, в этом проблема. Вы можете либо использовать какую-то отложенную анимацию после нажатия на контроллер представления и его представление действительно появилось, либо вы можете изменить макет пользовательского интерфейса без анимации - в этом случае он должен работать правильно. - person art-divin; 06.05.2013
comment
@ art-divin он отлично работает в моем фильме (см. мой ответ), и я показываю и скрываю панель навигации с анимацией. На самом деле без него все выглядит плохо. - person matt; 06.05.2013
comment
@matt ваша реализация отличается от авторской, я указывал на ошибку автора и обходной путь, который может сработать. Вы работаете, потому что отправку этих методов можно использовать с анимацией. Кстати, dispatch_get_main_queue () избыточен в -appDidFinishLaunchingWithOptions, потому что этот метод всегда вызывается в основном потоке - person art-divin; 06.05.2013
comment
@ art-divin (1) Код OP должен работать. Причина появления призрачной панели навигации неясна; происходит то, о чем ОП нам никогда не рассказывала. (2) Это не лишнее. Это задержка производительности, чтобы гарантировать ссылки. - person matt; 06.05.2013
comment
@matt, спасибо большое! setNavigationBarHidden, в то время как анимация push не очень хорошо работает в iOS 8.2, поэтому ваше решение спасло мне жизнь :) Но лучше заменить этот код в контроллере представления, когда вы хотите скрыть панель навигации, ИМХО - person aquarium_moose; 08.04.2015
comment
@matt Это решает проблему и для нас: что интересно, мерцание даже не ограничивается навигационной панелью, мерцает весь вид. С вашим подходом (willShowViewController) все работает. - person xaphod; 21.07.2015
comment
Бесконечно благодарен! У меня он работает идеально. Это моя быстрая версия - класс NavigationControllerDelegate: NSObject, UINavigationControllerDelegate {static let shared = NavigationControllerDelegate () func navigationController (_ NavigationController: UINavigationController, willShow viewController: UIViewController, animated: BoolavidBidController: анимированный: BoolavsetNavigationController (анимированный: BoolavsetNavigationController). }} - person Kamen Dobrev; 21.10.2020

Во втором контроллере представления скрыть панель навигации в viewWillAppear ::

self.navigationController.navigationBar.frame = CGRectMake(0, 0, 0, 0);

Чтобы отобразить панель навигации, установите рамку в viewWillDisappear:

self.navigationController.navigationBar.frame = CGRectMake(0, 0, 320, 44);
person Malathi    schedule 04.05.2013
comment
Это приводит к появлению черной полосы там, где раньше была панель навигации: i.imgur.com/YQdjNCS.png - person Doug Smith; 05.05.2013
comment
Переместить субпредставления на secondViewController вверх, т.е. изменить положение субпредставлений по оси Y - person Malathi; 06.05.2013
comment
Пожалуйста, для вашей собственной безопасности и безопасности всех остальных не начинайте возиться прямо с рамкой self.navigationController.navigationBar и жестко закодированными магическими числами. - person Mike Pollard; 22.05.2013

Ну, как я понял из вашего вопроса, единственная проблема вашего нынешнего подхода - временное появление оригинальной кнопки «Назад». Так почему бы просто не заблокировать эту кнопку для контроллера представления?

self.navigationItem.hidesBackButton = YES;

Думаю, это может помочь. Но для вашей основной задачи я бы предпочел использовать настраиваемую панель навигации с возможностью добавления любого количества кнопок. Такой подход более естественен для iOS, и вы, вероятно, никогда не столкнетесь с проблемами, о которых вы упомянули в своем вопросе.

person Andrey Chevozerov    schedule 24.05.2013

Здравствуйте! Следующие вещи сделали мою работу

В FirstViewController поместите этот метод

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:YES];
}

и в SecondViewController поместите этот метод

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [self.navigationController setNavigationBarHidden:YES animated:YES];
}

Я не использовал viewWillDisappear для своей работы.

Надеюсь вам поможет.

person Yuvrajsinh    schedule 07.05.2013

Это может быть так же просто, как переместить код с viewWillDisappear на viewDidDisappear.

Кроме того, избегайте использования анимации в любых методах отображения *, так как переход между представлениями уже анимируется.

person patric.schenke    schedule 22.05.2013

Моя проблема в том, что когда я нажимаю viewController с навигационной панелью на один без него, используя настраиваемый переход, перемещающий его с левой стороны, я не могу заставить его следовать за фреймом второго контроллера представления. Он всегда падает сверху, производя очень неприятный эффект, когда я выполняю это действие.

person user1785898    schedule 18.05.2014

Вы можете отобразить панель навигации, которая отобразит ее в родительском контроллере представления, а затем изменить альфа-канал с 0 на 1:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    self.navigationController.navigationBar.hidden = NO;
    self.navigationController.navigationBar.alpha = 0;

    [UIView animateWithDuration:0.3 animations:^{
        self.navigationController.navigationBar.alpha = 1;
    }];
}
person therin    schedule 05.04.2016