25

So I had a full working solution in iOS7 that displays a LoginViewController via presentViewController in the AppDelegate's didFinishLaunching.

Basically I am doing something like this:

UIViewController *backgroundViewController = ...
self.window.rootViewController = backgroundViewController;
[self.window makeKeyAndVisible];

[self.window.rootViewController presentViewController:loginViewController
                                             animated:NO ...]

In iOS8 I see a jump. First I see the backgroundViewController then after about 1 second or so the login appears.

So, how can I prevent this jump in iOS8?

I am seeing that are a ton of developers with this kind of problem but still didn't find a solution.

Tiago Almeida
  • 14,081
  • 3
  • 67
  • 82
  • Have you found a solution? I have seen the same issue with iOS 8 on iPhone 5S. But Xcode 6 simulator shows normal animation on iPhone 6/6+ simulators. – marsant Sep 19 '14 at 18:47
  • Also looking for a solution – SomeGuy Sep 20 '14 at 04:37
  • The simulator also has that issue, but you can't see it so clearly because it is faster. The only solution I found is to create that animation myself, via a container view controller. However, my solution has some issues with tabviewcontrollers :/ (viewDidAppear isn't called when we change viewcontrollers) – Tiago Almeida Sep 20 '14 at 14:34
  • 1
    I have the same issue and after some investigation I've found, that in my case the best solution is not to presenting loginViewController but setting self.window.rootViewController = loginViewController. And when I need do dismiss loginViewController, I'm setting self.window.rootViewController = backgroundViewController. I don't like this solution, but it works. – somedev Sep 24 '14 at 10:32
  • The downside is that you can't pre-load data in the backgroundViewController. Additionally, you can't have a more generic solution to present that login screen (if the user logs out, or the token expires, etc, you always had the same code and the only thing that changed was the animation flag). – Tiago Almeida Sep 24 '14 at 11:11
  • 1
    @somedev I ended up going that route, added posting a notification loginWillComplete where I switched the rootViewController, and thereafter continued my login process. Works like a charm. – Wilmar Nov 11 '14 at 08:41

5 Answers5

17

Also a hack (for now), but just one line of code

Add the view of the view controller you're presenting to the window before presentation

UIViewController *viewController = [[UIViewController alloc] init];
[viewController.view setBackgroundColor:[UIColor greenColor]];

//  Temporary iOS8 fix for 'presentation lag' on launch
[self.window addSubview:viewController.view];

[self.window.rootViewController presentViewController:viewController animated:NO completion:nil];

If you are presenting a navigation controller than add the navigation controller's view instead of its top view controller.

SomeGuy
  • 9,670
  • 3
  • 32
  • 35
2

I have a quick hacky fix:

//Make a screenshot of the ViewController first, or use a real image if you want

__block UIImageView *fakeImageView = [[UIImageView alloc] initWithImage:image];
fakeImageView.frame = vc.view.frame;
[self.view addSubview:fakeImageView];

[self presentViewController:vc animated:animated completion:^{
    [fakeImageView removeFromSuperview];
    fakeImageView = nil;
}];

It is not good for long term, but can quickly fix this issue without changing too much code.

Waiting for better solutions.

Meng Zhang
  • 191
  • 2
  • 5
1

You can set the window to an instance of a temporary controller.

self.window.backgroundColor = [UIColor whiteColor]; //do some styling etc.
self.window.rootViewController =  [LoginViewController new]; 
[self.window makeKeyAndVisible];

From the set controller (LoginViewController) you can push your real login controller with the desired transition. Once the login sequence is over you can make a transition from the login controller to the default application root view controller.

[UIView transitionWithView:[AppGlobal sharedApp].applicationWindow
  duration:0.75
  options:UIViewAnimationOptionTransitionFlipFromLeft
  animations:^{
   [AppGlobal sharedApp].applicationWindow.rootViewController = [AppRootViewController new];
  } completion:nil];
Slav
  • 101
  • 1
  • 4
0

I have also faced the same problem in iOS8 and I found this solution:

ABCViewController *obj = [[ABCViewController alloc] initWithNibName:@"ABCViewController" bundle:nil];                        

CATransition *transition = [CATransition animation];
transition.duration = 0.4;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromBottom;
transition.delegate = self;
[self.navigationControler.view.layer addAnimation:transition forKey:nil];
[appDelegate.navigationControler obj animated:NO];
 obj = nil;

I hope this solution can help you!

Tiago Almeida
  • 14,081
  • 3
  • 67
  • 82
-3

This should work: call [loginViewController view] Before presenting it.

JaganY
  • 53
  • 4