在IOS中,UINavigationController在添加(push)與刪除(pop)View的時候,會加入Slide的動畫。有時候,在需要自己進行類比這個動畫的時候,會比較麻煩。
通常,可以使用CATransition來使用Push效果,基本代碼如下:
CATransition *transition = [CATransition animation];
transition.duration = 0.3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.fillMode = kCAFillModeBackwards;
transition.speed = 0.5f ;
transition.removedOnCompletion = YES;
[self.view.layer removeAllAnimations];
[self.view.layer addAnimation:transition forKey:nil];
上面是Push的代碼,Pop的時候,只要將 subtype改為 kCATransitionFromLeft。
但是,使用CATransition的Push的時候,ios會將舊的view在推進中,進行Fade的處理。由於有這樣的一個過程,會造成螢幕的閃白,而且與原來的UINavigationController的動畫不一致。
要解決這個問題,只有使用暴力的方法,這個方法就是,先將原來的View進行截屏,產生一個UIImageView,再將這個UIImageView與新的View進行橫向的平移動畫,在動畫結束之後,再將新的UIImageView進行刪除。
截屏的代碼:
UIGraphicsBeginImageContext(viewController.view.bounds.size);
CALayer *layer = viewController.view.layer;
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image ;
再使用UIView的animation來實現,
[UIViewbeginAnimations:nilcontext:nil];
[UIViewsetAnimationDuration:0.35f];
[UIViewsetAnimationDelegate:self];
[UIViewsetAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
[UIViewsetAnimationCurve:UIViewAnimationCurveEaseInOut];
imageView.origin = CGPointMake(imageView.origin.x-screenRect.size.width, imageView.origin.y) ;
maskImageView.origin = CGPointMake(maskImageView.origin.x-screenRect.size.width, maskImageView.origin.y);
[UIViewcommitAnimations];
這個方法的缺點就是太過於暴力,在截屏的時候,會造成效能問題。