for the last few days I've been trying to figure out a way to do this:
Change to CollectionViewController if in landscape mode. Change to ViewController if in portrait mode.
Pretty much the way Music app behaves.
The way I did it was to implement viewWillTransitionToSize() in my main portraitViewController class:
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)
}
}
Main viewController(portraitViewController) contains a tableview and a searchController that has a searchBar on top.
In storyboard, portraitViewController is embedded in a navigation controller, collectionViewController(landscapeViewController) is on its own.
It runs, but I get the following 2 warnings:
Attempt to present UINavigationController on ViewController whose view is not in the window hierarchy!
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UISearchController)
Can someone point out what's going wrong here? If there's any tutorial/examples that can be of help I would greatly appreciate it! Thank you so much for your help
EDIT: Here is the final code that works
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 :(得分:0)
出现这些警告或错误的原因是,在解除和呈现视图控制器时出现延迟,并且您对呈现和解除的调用彼此重叠。
报告视图不在层次结构中的第一个错误意味着您尝试在原始视图控制器或导航控制器上显示一个不再可用的视图,因为另一个视图控制器已经过模态显示。
关于在解除分配时加载视图的第二个错误表示在尝试另一个模式演示时,视图控制器解雇还没有完全完成。
为了防止出现这些问题,需要在呈现新的视图控制器之前确保完成解雇。这可以通过在dismiss方法中使用完成处理程序处理状态并添加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)
}
}
}