问题
I am trying to understand the new segues in iOS 8. I have an app with a typical login screen shown initially, and if the user is logged in, that screen should not display (even for a split second) and user should be on a feed screen, which I am segueing from the initial login screen.
However, I am not able to do what I want. First of all, I can only use Present Modally segue, as it's the only appropriate segue that allows removing animation. Depending where I try to segue in view controller lifecycle, it either segues after initially displaying the login screen for a split second, or doesn't segue at all.
I am out of luck with viewDidAppear:
because it will always get executed after the initial view controller is displayed.
I am looking into viewDidLoad
and viewWillAppear:
but I get this on both (and nothing happens):
Warning: Attempt to present <UITabBarController: 0x12c617920> on <ViewController: 0x12c610590> whose view is not in the window hierarchy!
How can I display another view controller without displaying the initial view controller, even for a split second?
回答1:
I've developed well over 50 applications with more UI that I would probably like to. At the beginning, I also did the UI this way - have login controller first, then do seque, remove login controller.. The problem is that if your navigation tree grows more complicated, having login controller as your root starts to present serious issues.
UI Dispatcher
So what I am using now is to have my most used view controller as my root (in your case, that would be feed - but it also can be TabBarVC, navigation controller etc.), and login controller as modal view that is not connected to that navigation chain by any means. Then, I have Singleton that controls UI flow in the application (if you have bigger projects with multiple storyboards, I suggest you do that).
What the singleton does is that on application start, it checks for initial condition if it should present login form, and if yes it grabs it from storyboard (using Storyboard ID) + presents it as modal (not animate). This way, login is always visible on the first draw, but it does not have to if you don't want. You also don't have to change navigation tree / initial view controller.
To get controller from storyboard, you can use something like this:
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Login
func showLoginIfNeededAnimated(animated : Bool, completion : (() -> Void)?) {
// Show login if user is not logged-in, for example
if loginShouldAppearCondition {
// Instantiate login VC from storyboard
let storyboard : UIStoryboard = UIStoryboard(name: APPLICATION_UI_STORYBOARD_NAME_IPHONE_MAIN_FLOW, bundle: NSBundle.mainBundle())
let loginVC : LoginVC = storyboard.instantiateViewControllerWithIdentifier(STORYBOARD_NAME_LOGIN) as! LoginVC
// Present it
self.baseController.presentViewController(baseNC, animated: animated, completion: completion)
*Note - keep reference for login because of ARC!
}
}
I've noticed that Facebook uses something similar in their application, though I can't be sure about their implementation (I just seems to me like it due to way how they do animations).
Speaking of the animation, you can say that it does not provide you with push animation - well, you can always write your own if you wish to, but you can also create much more fancier effects. There is great tutorial on that topic (and also here), so you can check it to learn something interesting and possibly make your application better.
Hope it helps you and if you have any questions, just ask! I wish you good luck :)
回答2:
Kindly understand that Segue is just a ready-made development for Presenting and Pushing the controllers, which initially required a decent amount of code. The Segue is just a easier way to do this without writing much code to pass data and setting properties of other controller etc.
A segue is meaningless if it does not have a sourceViewController and a destinationViewController. And as it has sourceViewController, it needs to be loaded, and hence will appear always... If you need to know how to launch your App with a particular controller as your initial viewController, kindly see how you can set your Apps rootViewController...
But I am pretty sure, if you are trying to do it with Segue, your sourcController will appear, at least for a split of a Second.
来源:https://stackoverflow.com/questions/31514195/segueing-to-another-view-controller-without-displaying-the-first-in-ios-8