2015-10-30 1 views
1

за последние несколько дней я пытался выяснить способ сделать это:Как изменить ViewController на основе ориентации устройства

Переключает CollectionViewController если в ландшафтном режиме. Перейдите в ViewController, если в портретном режиме.

Практически так, как ведет себя приложение для музыки.

То, как я сделал это осуществить viewWillTransitionToSize() в моем главном классе portraitViewController:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { 

    let storyBoard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) 
    let portraitViewController = storyBoard.instantiateViewControllerWithIdentifier("portraitViewController") as! ViewController 
    let landscapeViewController = storyBoard.instantiateViewControllerWithIdentifier("landscapeViewController") as! beerCollectionViewController 

    if (UIDevice.currentDevice().orientation.isLandscape) { 
     // In landscape 

     presentViewController(landscapeViewController, animated: true, completion: nil) 

    } else { 
     // In portrait 

     self.navigationController?.presentViewController(portraitViewController, animated: true, completion: nil) 
     //let navVC = UINavigationController(rootViewController: portraitViewController) 
     //presentViewController(navVC, animated: true, completion: nil) 

     //Dismiss collectionViewController after switching back to portrait 
     self.dismissViewControllerAnimated(true, completion: nil) 
    } 

} 

Главная ViewController (portraitViewController) содержит TableView и searchController, который имеет SearchBar сверху.

В раскадровке PortraitViewController встроен в контроллер навигации, collectionViewController (LandscapeViewController) является самостоятельным.

Он работает, но я получаю следующие 2 предупреждения:

Попытка представить UINavigationController на ViewController чей вид не в иерархии окон!

Попытка загрузить вид контроллера представления во время его deallocating не допускается и может привести к непредсказуемому поведению (UISearchController)

Может кто-то указать на то, что происходит здесь не так? Если есть какой-нибудь учебник/примеры, которые могут помочь, я бы очень признателен! Большое вам спасибо за вашу помощь

EDIT: Вот окончательный код, который работает

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { 

    let storyBoard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) 

    // In landscape 
    if UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation) { 
     let landscapeVC = storyBoard.instantiateViewControllerWithIdentifier("landscapeViewController") as! beerCollectionViewController 
     if presentedViewController != nil { 
      if !presentedViewController!.isBeingDismissed() { 
       self.dismissViewControllerAnimated(false, completion: { 
        self.presentViewController(landscapeVC, animated: true, completion: nil) 
       }) 
      } 
     } else { 
      self.presentViewController(landscapeVC, animated: true, completion: nil) 
     } 

    } 
    // In portrait 
    else { 
     let navC = storyBoard.instantiateViewControllerWithIdentifier("navID") as! UINavigationController 
     let portraitVC = storyBoard.instantiateViewControllerWithIdentifier("portraitViewController") as! ViewController 

     if presentedViewController != nil { 
      if !presentedViewController!.isBeingDismissed() { 
       self.dismissViewControllerAnimated(false, completion: { 
        navC.pushViewController(portraitVC, animated: true) 
       }) 
      } 
     } else { 
      navC.pushViewController(portraitVC, animated: true) 
     } 
    } 

ответ

0

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

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

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

Для предотвращения этих проблем необходимо обеспечить завершение увольнения перед представлением нового контроллера вида. Это может быть выполнено путем обработки состояний с использованием обработчика завершения в методах увольнения и добавления проверки состояния isBeingDismissed.

Вот код, который выполняет следующее:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { 
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) 

    let storyboard = UIStoryboard(name: "Main", bundle: nil) 

    if UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation) { 
     let landscapeVC = storyboard.instantiateViewControllerWithIdentifier("landscapeViewController") as! beerCollectionViewController 

     if presentedViewController != nil { 
      if !presentedViewController!.isBeingDismissed() { 
       dismissViewControllerAnimated(false, completion: { 
        self.presentViewController(landscapeVC!, animated: true, completion: nil) 
       }) 
      } 
     } else { 
      self.presentViewController(landscapeVC!, animated: true, completion: nil) 
     } 
    } else { // Portrait 
     let portraitVC = storyboard.instantiateViewControllerWithIdentifier("portraitViewController") as! ViewController 

     if presentedViewController != nil { 
      if !presentedViewController!.isBeingDismissed() { 
       dismissViewControllerAnimated(false, completion: { 
        self.presentViewController(portraitVC!, animated: true, completion: nil) 
       }) 
      } 
     } else { 
      self.presentViewController(portraitVC!, animated: true, completion: nil) 
     } 
    } 
} 
+0

Спасибо так много! Теперь я знаю, почему это бросало эти ошибки. Однако я заметил, что когда я вернусь к портрету, панель навигации исчезла. Это потому, что я только представляю портрет viewController, а не контроллер навигации, в который встроен портрет viewController? – yfcosy

+0

Добро пожаловать.Вы можете получить панель навигации, создав ее из раскадровки, как в 'storyboard.instantiateViewControllerWithIdentifier (" ") как? UINavigationController' и представляет навигационный контроллер. Возможно, вам придется добавить их в свою раскадровку и подключить их к вашему VC с шоу-сегу. Насколько мне известно, модальные презентации не используют предыдущий стек навигационного контроллера. Альтернативой является толкать/поп-просмотр контроллеров на существующий стек ЧПУ. – Daniel

+0

В портретном режиме я объявил 'let navC = storyBoard.instantiateViewControllerWithIdentifier (« navID ») как! UINavigationController', затем используется 'navC.pushViewController (portraitVC, animated: true)', и теперь все предупреждения исчезли. Нужно больше копать в том, как представить viewController, но я думаю, что здесь есть некоторые базовые понятия. Еще раз спасибо! – yfcosy

 Смежные вопросы

  • Нет связанных вопросов^_^