ViewWillAppear called twice with custom segue animation using FromView transition

I am looking to run a segue to replace the window root window controller with another view controller using swirling animations. The idea is that I show the SplashViewController for a few seconds before moving on ( performSegueWithIdentifier: to the next one, LoginViewController , using the curl up animation.

I created my own UIStoryboardSegue class called AnimatedSegue . Here is the code for the overridden perform method:

 - (void)perform { UIViewController *source = self.sourceViewController; UIViewController *destination = self.destinationViewController; UIWindow *window = source.view.window; [UIView transitionFromView:source.view toView:destination.view duration:1.0 options:UIViewAnimationOptionTransitionCurlUp completion:^(BOOL finished) { [window setRootViewController:destination]; }]; } 

It works fine, except in iOS 6 (apparently not in iOS 5) the viewWillAppear: method viewWillAppear: is called twice on the destination view controller. It seems that he called the first time during the transition and the second time he executes [window setRootViewController:destination];

Please note that I do not want to use the navigation controller. SplashViewController freed up (as expected) after the transition is complete.

Any ideas on how to fix my problem?

+7
source share
3 answers

Answering my question if he can help someone else ...

I ended up using Core Animation CATransition to create segue animations instead of UIView animation UIView .

Here's what my new perform method looks like:

 - (void)perform { UIViewController *source = self.sourceViewController; UIWindow *window = source.view.window; CATransition *transition = [CATransition animation]; [transition setDuration:1.0]; [transition setDelegate:self]; [transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]]; [transition setType:@"pageCurl"]; [transition setSubtype:kCATransitionFromBottom]; [window.layer addAnimation:transition forKey:kCATransition]; [window setRootViewController:self.destinationViewController]; } 
+10
source

I would do it differently using 2 views and one controller, not 2 controllers with custom segue. In your storyboard, just start an empty controller for the controller and add two xib files (of the view type) with a splash view and the main view. The splash look will be added as a subview of the controller in viewDidLoad, and then turned off using the same method you did:

 @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.splashView = [[NSBundle mainBundle] loadNibNamed:@"SplashView" owner:self options:nil].lastObject; [self.view addSubview:self.splashView]; [self performSelector:@selector(removeSplash) withObject:nil afterDelay:2]; } -(void)removeSplash { self.mainView = [[NSBundle mainBundle] loadNibNamed:@"MainView" owner:self options:nil].lastObject; [UIView transitionFromView: self.splashView toView:self.mainView duration:.6 options:UIViewAnimationOptionTransitionCurlUp completion:nil]; } 
+2
source

If you really want to use transitionFromView: only thing I can find is just to take a screenshot of the original view controller and animate it.

 - (void)perform { UIViewController *source = self.sourceViewController; UIViewController *destination = self.destinationViewController; // Create screenshot for animation UIGraphicsBeginImageContextWithOptions(source.view.bounds.size, NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); [source.view.layer renderInContext:context]; UIImageView *screenShot = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; UIGraphicsEndImageContext(); // Put destination view controller and screen shot in place UIWindow *window = source.view.window; window.rootViewController = destination; [window addSubview:screenShot]; [UIView transitionFromView:screenShot toView:destination.view duration:1.0 options:UIViewAnimationOptionTransitionCurlUp completion:^(BOOL finished) { }]; } 

viewWillAppear: and its ilk is called only once, as expected.

+1
source

All Articles