iOS自定義轉場動畫無法用presentingViewControll(fromView)中的view問題
問題描述
- 最近自己實作一個淘寶購物車動畫效果(控制器A modal 一個控制器B,A的控制器view後移并實作一個動畫效果,b控制器展現一部分),發現無法改變控制器A的view
效果圖

————>
- 動畫播放器中Animator中主要代碼如下(ps:modalPresentationStyle為custom)
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{ static int flag = 0; //flag 确定是點選購物車,還是傳回 flag++; UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; UIView *destinationView = [transitionContext viewForKey:UITransitionContextToViewKey]; if (flag % 2) { //動畫效果處理 [[transitionContext containerView] addSubview:destinationView]; CATransform3D transform = CATransform3DIdentity; transform.m34 = -0.001; transform = CATransform3DRotate(transform, M_PI_4 * .2, 1, 0, 0); transform = CATransform3DTranslate(transform, 0, 0, -100); [UIView animateWithDuration:[self transitionDuration:nil] * 0.5 animations:^{ fromView.layer.transform = transform; } completion:^(BOOL finished) { [UIView animateWithDuration:[self transitionDuration:nil] * 0.5 animations:^{ fromView.layer.transform = CATransform3DMakeScale(.9, .9, 1); } completion:nil]; }]; destinationView.frame = [UIScreen mainScreen].bounds; destinationView.transform = CGAffineTransformTranslate(destinationView.transform, 0, kScreenBounsSize.height - 400); [UIView animateWithDuration:[self transitionDuration:nil] animations:^{ destinationView.transform = CGAffineTransformIdentity; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; }else{ [UIView animateWithDuration:[self transitionDuration:nil] animations:^{ fromView.transform = CGAffineTransformTranslate(fromView.transform, 0, kScreenBounsSize.height - 400); destinationView.layer.transform = CATransform3DIdentity; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } }
解決辦法
- 将
和fromView
直接從控制器調用destinationView
- 即将
改為UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; UIView *destinationView = [transitionContext viewForKey:UITransitionContextToViewKey];
UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view; UIView *destinationView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
原因
- 我們将代碼改為
和UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
列印發現UIView *destinationView = [transitionContext viewForKey:UITransitionContextToViewKey];
出現了null:fromView
2017-02-22 11:33:49.254 taobaoEffect[1376:323552] fromView ----- (null) 2017-02-22 11:33:49.255 taobaoEffect[1376:323552] destinationView ----- <UIView: 0x7fb433c03690; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x60000005e540>; layer = <CALayer: 0x60000002e0c0>>
- 這裡似乎沒有任何問題,看文檔也沒有任何解釋。但這又是一個Apple的一個坑,這在預設的文檔下是沒有的,但如果你下載下傳文檔了以後再看,你會發現在
方法中會有這麼解釋(Apple提醒你文檔的重要性again) viewForKey: may return nil which would indicate that the animator should not manipulate the associated view controller’s view. 當viewController的view不該被animator所操作時,将傳回nilviewForKey:
// Currently only two keys are defined by the system - // UITransitionContextFromViewKey, and UITransitionContextToViewKey // viewForKey: may return nil which would indicate that the animator should not // manipulate the associated view controller's view. - (nullable __kindof UIView *)viewForKey:(UITransitionContextViewKey)key NS_AVAILABLE_IOS(8_0);
具體代碼
https://github.com/NewYorkFive/taobaoShopListAnimator_Demo/tree/master