我嚴重不相信有一些的UIViewController這個概念展現UISplitViewController (例如登錄表單)原來是這麼複雜,直到我不得不創建一個樣的觀點hiearchy之前。我的例子基於iOS 8和XCode 6.0(Swift),所以我不確定這個問題是否以同樣的方式存在,或者是由於iOS 8引入了一些新的錯誤,但是從所有我發現的類似問題,我沒有看到這個問題的完整'不是很hacky'的解決方案。
我會指導您完成一些我在結束解決方案之前嘗試過的一些事情(在本文結尾處)。每個示例均基於在未啓用CoreData的情況下從Master-Detail模板創建新項目。
第一次嘗試(模態SEGUE到UISplitViewController):
- 創建新UIViewController子類(LoginViewController例如)
- 在故事板中添加新的視圖控制器,其設置爲初始視圖控制器(代替UISplitViewController的),並把它連接到LoginViewController
- 添加的UIButton到LoginViewController,並從該按鈕創建模態順着接下去UISplitViewController
爲UISplitViewController
- 移動樣板設置代碼從AppDelegate中的
didFinishLaunchingWithOptions
到LoginViewController的prepareForSegue
這幾乎工作。我差不多說了,因爲在應用程序啓動後使用LoginViewController並點擊按鈕並繼續使用UISplitViewController,出現了一個奇怪的錯誤:顯示和隱藏主視圖控制器在方向更改不再動畫。
後,這個問題並沒有真正解決一段時間掙扎,我認爲它以某種方式與奇怪的規則是UISplitViewController必須是RootViewController的連接(在這種情況下它是不是,LoginViewController是),所以我給了從這個不完美的解決方案。
第二個嘗試(從UISplitViewController模式賽格瑞):
- 創造新的UIViewController子類(LoginViewController例如)
- 在故事板添加新的視圖控制器,並將其連接到LoginViewController(但此時讓UISplitViewController成爲初始視圖控制器)
- 從UISplitViewController創建模態segue到LoginViewController
- add UIB utton到LoginViewController,並從該按鈕創建開卷賽格瑞
最後,添加以下代碼到AppDelegate中的didFinishLaunchingWithOptions
樣板代碼後設立UISplitViewController:
window?.makeKeyAndVisible()
splitViewController.performSegueWithIdentifier("segueToLogin", sender: self)
return true
或與此代碼,而不是嘗試:
window?.makeKeyAndVisible()
let loginViewController = splitViewController.storyboard?.instantiateViewControllerWithIdentifier("LoginVC") as LoginViewController
splitViewController.presentViewController(loginViewController, animated: false, completion: nil)
return true
這兩個例子都會產生相同的幾個不好的東西:
個
- 控制檯輸出:
Unbalanced calls to begin/end appearance transitions for <UISplitViewController: 0x7fc8e872fc00>
- UISplitViewController必須首先顯示LoginViewController有模式地segued之前(我寧願只存在登錄表單,因此用戶不會看到UISplitViewController登錄之前)
- 開卷賽格瑞沒有得到所謂的(這完全是其他錯誤,我不會進入那個故事現在)
解決方案(更新RootViewController的)
我發現的唯一途徑,其正常工作是如果你改變窗口RootViewController的對飛:
- 定義故事板ID爲LoginViewController和UISplitViewController, 並添加某種的loggedIn屬性到AppDelegate中。
- 基於此屬性,實例化適當的視圖控制器,然後將其設置爲rootViewController。
- 在
didFinishLaunchingWithOptions
中沒有動畫的情況下執行動畫,但在從UI調用時動畫。
下面是從AppDelegate中的示例代碼:
var loggedIn = false
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
setupRootViewController(false)
return true
}
func setupRootViewController(animated: Bool) {
if let window = self.window {
var newRootViewController: UIViewController? = nil
var transition: UIViewAnimationOptions
// create and setup appropriate rootViewController
if !loggedIn {
let loginViewController = window.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("LoginVC") as LoginViewController
newRootViewController = loginViewController
transition = .TransitionFlipFromLeft
} else {
let splitViewController = window.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("SplitVC") as UISplitViewController
let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as UINavigationController
navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem()
splitViewController.delegate = self
let masterNavigationController = splitViewController.viewControllers[0] as UINavigationController
let controller = masterNavigationController.topViewController as MasterViewController
newRootViewController = splitViewController
transition = .TransitionFlipFromRight
}
// update app's rootViewController
if let rootVC = newRootViewController {
if animated {
UIView.transitionWithView(window, duration: 0.5, options: transition, animations: {() -> Void in
window.rootViewController = rootVC
}, completion: nil)
} else {
window.rootViewController = rootVC
}
}
}
}
這是從LoginViewController示例代碼:
@IBAction func login(sender: UIButton) {
let delegate = UIApplication.sharedApplication().delegate as AppDelegate
delegate.loggedIn = true
delegate.setupRootViewController(true)
}
我也想聽到的話,有一些更好的/清潔的方式,使其在iOS 8中正常工作。
如何將菜單視圖作爲全屏模式對話框推送到UISplitViewController上?我有同樣的問題,我從故事板中的分割視圖菜單視圖中定義模式segue,然後在我的splitviewcontroller代碼中使用viewDidApear中的performSegueWithIdentifier:但這種方式用戶總是在菜單模式之前看到分割視圖的一瞥?這個問題能解決嗎?我應該在哪裏調用performseguewithidentifier來防止這個問題? – 2012-02-20 16:19:30