我正在编写一个在表格视图中包含一系列卡片的应用程序,类似于启用 Google Now 卡片时适用于 iOS 的 Google 应用程序的布局。当用户点击一张卡片时,应该有一个自定义的过渡到一个新的视图控制器,基本上卡片看起来更大,几乎填满了屏幕,并且上面有更多的细节。自定义转换本身应该看起来像卡片向上动画并增大大小,直到达到最终大小和位置,现在是持有卡片的新视图控制器。
我一直在尝试使用自定义视图控制器转换来解决这个问题。当卡片被点击时,我使用 启动一个自定义视图控制器转换UIModalPresentationCustom
,并设置一个转换委托,它本身提供一个自定义动画师和一个自定义 UIPresentationController。在animateTransition:
中,我将新视图控制器的视图添加到容器视图中,最初将框架设置为卡片的框架(因此看起来卡片仍然存在且未更改)。然后我尝试执行一个动画,其中呈现的视图的框架尺寸增加并改变位置,以便它移动到最终位置。
这是我上面描述的一些代码 - 我试图保持简短和甜蜜,但如果需要我可以提供更多信息:
过渡代表
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
// NOWAnimationDelegate is my own custom protocol which defines the method for asking the presenting VC for the tapped card's frame.
UIViewController<NOWAnimationDelegate> *fromVC = (UIViewController<NOWAnimationDelegate> *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *finalVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
// Ask the presenting view controller for the frame of the tapped card - this method works.
toView.frame = [fromVC rectForSelectedCard];
[transitionContext.containerView addSubview:toView];
CGRect finalRect = [transitionContext finalFrameForViewController:finalVC];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toView.frame = finalRect;
}completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
自定义 UIPresentationController
-(CGSize)sizeForChildContentContainer:(id<UIContentContainer>)container withParentContainerSize:(CGSize)parentSize {
return CGSizeMake(0.875*parentSize.width, 0.875*parentSize.height);
}
-(CGRect)frameOfPresentedViewInContainerView {
CGRect presentedViewFrame = CGRectZero;
CGRect containerBounds = self.containerView.bounds;
presentedViewFrame.size = [self sizeForChildContentContainer:(UIView<UIContentContainer> *)self.presentedView withParentContainerSize:containerBounds.size];
presentedViewFrame.origin.x = (containerBounds.size.width - presentedViewFrame.size.width)/2;
presentedViewFrame.origin.y = (containerBounds.size.height - presentedViewFrame.size.height)/2 + 10;
return presentedViewFrame;
}
我发现正在发生的是新视图在动画开始时立即自动设置为其最终大小,然后动画只是向上动画的新视图。使用断点,我注意到frameOfPresentedViewInContainerView
在调用期间[transitionContext.containerView addSubview:toView]
调用了它,这可能可以解释为什么会发生这种情况 -frameOfPresentedViewInContainerView
根据 UIPresentationController 文档返回“在动画结束时分配给呈现视图的框架矩形”。
但是,我不确定如何进行,或者是否真的有可能。我见过的所有自定义视图控制器转换的示例都具有呈现的视图控制器的最终大小,并且在动画期间保持不变。有没有办法在动画期间通过改变呈现视图的大小来执行自定义视图控制器转换,还是我必须以不同的方式处理这个?