iOS-自定义交互式转场动画
程序员文章站
2022-03-25 09:09:42
...
自定义转场动画主要有以下步骤
- 自定义导航栏
- 自定义交互动画
- 通过UIPercentDrivenInteractiveTransition协议实现交互
自定义导航栏
自定义导航栏需要遵守<UINavigationControllerDelegate>协议,该协议主要有两个协议方法:
// 该方法返回导航跳转时的动画,如果返回nil,则是系统默认的跳转动画,并且通过operation来判断当前执行push还是pop
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
return nil;
}
// 该方法返回自定义交互动画,只有实现该协议,才能在跳转时实现与用户交互
-(id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
return nil;
}
自定义跳转动画
自定义跳转动画需要遵守<UIViewControllerAnimatedTransitioning>协议,该协议主要实现下面的方法:
// 该方法返回动画执行的时间,transitionContext由系统获取
-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 0.3;
}
// 通过该协议,获取跳转的两个VC
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[self animateTransition:transitionContext fromVC:fromVC toVC:toVC fromView:fromVC.view toView:toVC.view];
}
// 这是模仿系统导航跳转的例子
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView{
[[transitionContext containerView] addSubview:toView];
if (_isPush) {
[[transitionContext containerView] bringSubviewToFront:toView];
toView.transform = CGAffineTransformMakeTranslation(-toView.bounds.size.width, 0);
}
else{
[[transitionContext containerView] bringSubviewToFront:fromView];
}
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
if (_isPush) {
toView.transform = CGAffineTransformIdentity;
}
else{
fromView.transform = CGAffineTransformMakeTranslation(-fromView.bounds.size.width, 0);
}
} completion:^(BOOL finished) {
transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
实现交互
自定义一个类,继承自UIPercentDrivenInteractiveTransition,它遵守<UIViewControllerInteractiveTransitioning>协议,我们可以告诉它当前转场动画进行的百分比,它再来更新动画的进度。转场动画进行的百分比可以通过手势来计算
// 在view上加入pan手势
UIPanGestureRecognizer *gesture = objc_getAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey));
if (gesture) {
[self.interactiveVC.view removeGestureRecognizer:gesture];
}
gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
[self.interactiveVC.view addGestureRecognizer:gesture];
objc_setAssociatedObject(self.interactiveVC.view, (__bridge const void *)(kpanGestureKey), gesture,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// 当pan手势移动,通过移动的距离来计算当前跳转动画需要完成的百分比,当手势结束时,判断动画完成的百分比。如果>50%,finishInteractiveTransition完成跳转动画;如果<50%,cancelInteractiveTransition取消动画,返回原样
case UIGestureRecognizerStateChanged:
CGFloat fraction = point.x / [[UIScreen mainScreen] bounds].size.width;
fraction = fminf(fmaxf(fraction, 0.0), 1.0);
self.shouldComplete = (fraction > 0.5);
[self updateInteractiveTransition:fraction];
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
self.interactioning = NO;
if (!self.shouldComplete || pan.state == UIGestureRecognizerStateCancelled) {
[self cancelInteractiveTransition];
}
else {
[self finishInteractiveTransition];
}
break;
最后附上Demo的地址https://github.com/cdcyd/CommonControlsCollection
上一篇: 浅谈URL重定向
下一篇: 机器学习中的标准化/归一化