-->

presentViewController in AppDelegate with delay in

2020-05-20 08:32发布

问题:

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.

回答1:

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.



回答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.



回答3:

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];


回答4:

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!



回答5:

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