轉(zhuǎn)場動(dòng)畫學(xué)習(xí)中...TransitionDemo代碼
實(shí)現(xiàn)自定義的轉(zhuǎn)場動(dòng)畫(只涉及自定義動(dòng)畫,不管手勢驅(qū)動(dòng))
涉及三個(gè)協(xié)議:
UIViewControllerAnimatedTransitioning(動(dòng)畫處理)
UIViewControllerTransitioningDelegate(頁面modal時(shí)指定相關(guān)動(dòng)畫代理)
UINavigationControllerDelegate(頁面push/pop時(shí)指定相關(guān)動(dòng)畫代理)
-
自定義動(dòng)畫類, 遵守協(xié)議UIViewControllerAnimatedTransitioning并實(shí)現(xiàn)相關(guān)動(dòng)畫(類CircleSpreadAnimation)
#pragma mark - UIViewControllerAnimatedTransitioning /** 動(dòng)畫時(shí)長 */ - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{ return self.duration; } /** 動(dòng)畫:步驟2、4不能省 */ - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{ // 1.獲取ToVC UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // 2.將ToVC's View 添加到containerView中 UIView *containerView = [transitionContext containerView]; [containerView addSubview:toVC.view]; // 3.圓形擴(kuò)散動(dòng)畫厕吉,對ToVC's View進(jìn)行動(dòng)畫處理 CGSize size = containerView.frame.size; CGPoint beginP = CGPointMake(size.width*0.5, size.height);//中下 switch (self.direction) { case CircleSpreadAnimationDirectionDown: beginP = CGPointMake(size.width*0.5, 0);//中上 break; case CircleSpreadAnimationDirectionRight: beginP = CGPointMake(0, size.height*0.5);//左中 break; case CircleSpreadAnimationDirectionLeft: beginP = CGPointMake(size.width, size.height*0.5);//右中 break; default: break; } UIBezierPath *beginPath = [UIBezierPath bezierPathWithArcCenter:beginP radius:1 startAngle:0 endAngle:M_PI*2 clockwise:YES]; CGFloat endX = beginP.x>size.width*0.5? beginP.x : size.width - beginP.x; CGFloat endY = beginP.y>size.height*0.5? beginP.y : size.height - beginP.y; CGFloat endRadius = sqrt(pow(endX, 2) + pow(endY, 2)); UIBezierPath *endPath = [UIBezierPath bezierPathWithArcCenter:beginP radius:endRadius startAngle:0 endAngle:M_PI*2 clockwise:YES]; CAShapeLayer *maskLayer = [CAShapeLayer layer]; maskLayer.path = endPath.CGPath; toVC.view.layer.mask = maskLayer; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"]; animation.fromValue = (__bridge id )(beginPath.CGPath); animation.toValue = (__bridge id )(endPath.CGPath); animation.duration = self.duration; animation.delegate = self; [animation setValue:transitionContext forKey:@"transitionContext"]; [maskLayer addAnimation:animation forKey:@"pushPath"]; } -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ id<UIViewControllerContextTransitioning> transitionContext = [anim valueForKey:@"transitionContext"]; // 4.告知完成 [transitionContext completeTransition:YES]; }
-
自定義轉(zhuǎn)場動(dòng)畫:(相關(guān)類FromViewController蚜点、ToViewController)
-
修改轉(zhuǎn)場代理(為簡化阁危,直接讓FromViewController成為轉(zhuǎn)場代理)
/** 從FromViewController 跳轉(zhuǎn)到 ToViewController捆姜,使FromViewController成為轉(zhuǎn)場代理 */
- (void)toBtnClicked{ToViewController *toVC = [[ToViewController alloc] init]; // 1.更換動(dòng)畫過渡代理 // self是FromViewController if (self.push) { // push時(shí)修改navigationController的代理 self.navigationController.delegate = self; [self.navigationController pushViewController:toVC animated:YES]; } else { // present時(shí)修改transitioningDelegate的代理 toVC.transitioningDelegate = self; [self presentViewController:toVC animated:YES completion:nil]; } }
實(shí)現(xiàn)代理锌俱,返回相關(guān)動(dòng)畫代理實(shí)例;
-
modal : FromViewController遵守協(xié)議
UIViewControllerTransitioningDelegate#pragma mark - UIViewControllerTransitioningDelegate // 2.modal方式:指定自定義的動(dòng)畫代理 - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{ // present的時(shí)候的動(dòng)畫代理 return self.circleAnimationUP; // nil代表使用默認(rèn)過渡效果 //return nil; } - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{ // dismiss的時(shí)候的動(dòng)畫代理 return self.circleAnimationDown; // nil代表使用默認(rèn)過渡效果 //return nil; }
-
push/pop:FromViewController遵守協(xié)議
UINavigationControllerDelegate#pragma mark - UINavigationControllerDelegate // 2.push/pop方式:指定自定義的動(dòng)畫代理 - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{ // 設(shè)置自定義動(dòng)畫 id<UIViewControllerAnimatedTransitioning> animation = nil;//使用默認(rèn)效果 if (operation == UINavigationControllerOperationPush) { // push的時(shí)候的動(dòng)畫代理 animation = self.circleAnimationLeft; } else if (operation == UINavigationControllerOperationPop) { // pop的時(shí)候的動(dòng)畫代理 animation = self.circleAnimationRight; } // 3.以便在pop到當(dāng)前頁面的時(shí)候恢復(fù)默認(rèn)轉(zhuǎn)場效果 if (toVC == self) { self.navigationController.delegate = nil; } return animation; }
-
參考
WWDC 2013 Session筆記 - iOS7中的ViewController切換
幾句代碼快速集成自定義轉(zhuǎn)場效果+ 全手勢驅(qū)動(dòng)