При использовании Hidesbottombar whenpushed я хочу, чтобы панель вкладок появлялась снова, когда я нажимаю на другой вид

#iphone #objective-c #uinavigationcontroller #uitabbar

#iPhone #objective-c #uinavigationcontroller #uitabbar

Вопрос:

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

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.hidesBottomBarWhenPushed = YES; // To hide the tab bar
    }
    return self;
}
  

Но для следующего представления, которое я нажимаю на стек, я хочу, чтобы панель вкладок появлялась снова. Есть ли способ сделать это?

Ответ №1:

Начиная с iOS5, есть очень простой способ добиться этого. По сути, это тот же метод, что и Deepak, но в анимации нет никаких артефактов — все выглядит так, как ожидалось.

При инициализации установите

 self.hidesBottomBarWhenPushed = YES;
  

точно так же, как у вас выше. Когда пришло время вставить новый контроллер в стек, это так же просто, как:

 self.hidesBottomBarWhenPushed = NO;

UIViewController *controller = [[[BBListingController alloc] init] autorelease];
[self.navigationController pushViewController:controller];

self.hidesBottomBarWhenPushed = YES;
  

Важно сбросить значение на YES после нажатия контроллера, чтобы повторно скрыть панель, когда пользователь нажимает кнопку «Назад» и просмотр возвращается в режим просмотра.

Комментарии:

1. Это работает, но проблема в том, что если controller нажать другой контроллер, нижняя панель будет скрыта.

Ответ №2:

Я решил эту проблему следующим образом:

Почти все мои ViewControllers являются дочерними элементами BaseViewController.

Итак, пример:

 class BaseVC: UIViewController {
    final override var hidesBottomBarWhenPushed: Bool {
        get {
            if navigationController?.viewControllers.last == self {
                return prefersBottomBarHidden ?? super.hidesBottomBarWhenPushed
            } else {
                return false
            }
        } set {
            super.hidesBottomBarWhenPushed = newValue
        }
   }
   private(set) var prefersBottomBarHidden: Bool?
}
  

Просто переопределите переменную «prefersBottomBarHidden» в ViewController, где нижняя панель должна быть скрыта:

 override var prefersBottomBarHidden: Bool? { return true }
  

Комментарии:

1. Это должно быть принятым решением. Это хорошо работает при нажатии и отображении комбинации контроллеров, которые хотят или не хотят, чтобы нижняя панель была скрыта. Спасибо!

2. Похоже, это единственное надежное решение, особенно если вы используете правильную архитектуру кода, которая не запускает другие виртуальные машины из VC. Было бы лучше, если бы это был протокол, поскольку я хочу избежать объявления всех моих VCS как подкласса базового VC, но поскольку нам нужно переопределить hidesBottomBarWhenPushed протокол, это невозможно. Теперь, если бы только это также решило проблему, связанную с splitViewController, я был бы очень счастлив 🙂 => openradar.appspot.com/24846972

3. @mathz вы уже нашли решение для splitViewController?

Ответ №3:

Прошло некоторое время с тех пор, как был задан этот вопрос, но ни один из этих ответов не касается использования переходов раскадровки. Оказывается, это довольно просто:

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "MyViewControllerIdentifier" {

        // Hide the tabbar during this segue
        hidesBottomBarWhenPushed = true

        // Restore the tabbar when it's popped in the future
        DispatchQueue.main.async { self.hidesBottomBarWhenPushed = false }

    }
}
  

Ответ №4:

Можно заставить ее появиться снова, но это приведет к неправильной анимации. Страница отображается слева, а нижняя панель справа. Так что, вероятно, это не то поведение, которое вы хотите. Но в том же контроллере сделайте self.hidesBottomBarWhenPushed = NO; , прежде чем вводить следующий view controller.

Комментарии:

1. Это действительно работает, однако это означает, что нижняя панель перемещается слева, в то время как недавно перемещенный view перемещается справа — это выглядит очень сбивающим с толку. Так что другой вариант был бы хорош. Может быть, мне нужно установить ее рамку?

Ответ №5:

Случай первый: чтобы скрыть UITabBarController в cetain UIViewController, например, во время вызова self.performSegueWithIdentifier("Identifier", sender: self) , необходимо предварительно установить self.hidesBottomBarWhenPushed = true флаг. И после self.hidesBottomBarWhenPushed = false флага. Но мы должны понимать, что через один UIViewController UITabBarController снова появится и, в случае, если вам нужно использовать UITabBarController с одним UIViewController, это не даст правильного результата.

в FirstItemViewController

     @IBAction func pushToControllerAction(sender: AnyObject) {
        self.hidesBottomBarWhenPushed = true
        self.performSegueWithIdentifier("nextController", sender: self)
        self.hidesBottomBarWhenPushed = false
    }
  

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

Случай второй:
Чтобы скрыть UITabBarController в определенном UIViewController, после чего UITabBarController должен быть извлечен, необходимо, например, при вызове self.performSegueWithIdentifier("nextController", sender: self) установить self.hidesBottomBarWhenPushed = true перед методом. Также willMoveToParentViewController(parent: UIViewController?) в методе должно быть настроено, как показано в примере кода.

в первом UIViewController «FirstItemViewController»

  @IBAction func pushToControllerAction(sender: AnyObject) {
     self.hidesBottomBarWhenPushed = true
     self.performSegueWithIdentifier("nextController", sender: self)
 }
  

в следующем UIViewController «ExampleViewController»`

  override func willMoveToParentViewController(parent: UIViewController?) {
         if parent == nil {
             var viewControllers = self.navigationController!.viewControllers
             if ((viewControllers[viewControllers.count - 2]).isKindOfClass(FirstItemViewController.self)) {
                 (viewControllers[viewControllers.count - 2] as! FirstItemViewController).hidesBottomBarWhenPushed = false
             }
         }
 }
  

Код Swift 3:

 let viewControllers = self.navigationController!.viewControllers
                if ((viewControllers[viewControllers.count - 2]) is (FirstItemViewController)) {
                    (viewControllers[viewControllers.count - 2] as! FirstItemViewController).hidesBottomBarWhenPushed = false
                }
  

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

Тестовый проект

Ответ №6:

В корневом контроллере представления «A» (который показывает панель вкладок), когда придет время показывать другой контроллер представления «B», где панель вкладок не требуется:

 self.hidesBottomBarWhenPushed = YES; // hide the tabBar when pushing B
[self.navigationController pushViewController:viewController_B animated:YES];
self.hidesBottomBarWhenPushed = NO; // for when coming Back to A
  

В контроллере просмотра B, когда придет время показывать третий контроллер просмотра C (панель вкладок снова требуется):

 self.hidesBottomBarWhenPushed = NO; // show the tabbar when pushing C
[self.navigationController pushViewController:viewController_C animated:YES];
self.hidesBottomBarWhenPushed = YES; // for when coming Back to B