iOS-自定义交互式转场动画
自定义转场动画主要有以下步骤
- 自定义导航栏
- 自定义交互动画
- 通过UIPercentDrivenInteractiveTransition协议实现交互
// 该方法返回导航跳转时的动画,如果返回nil,则是系统默认的跳转动画,并且通过operation来判断当前执行push还是pop
-(id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
return nil;
}
// 该方法返回自定义交互动画,只有实现该协议,才能在跳转时实现与用户交互
-(id)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id)animationController
{
return nil;
}
自定义跳转动画 自定义跳转动画需要遵守
// 该方法返回动画执行的时间,transitionContext由系统获取
-(NSTimeInterval)transitionDuration:(id)transitionContext
{
return 0.3;
}
// 通过该协议,获取跳转的两个VC
-(void)animateTransition:(id)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)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]];
}];
}
实现交互 【iOS-自定义交互式转场动画】自定义一个类,继承自UIPercentDrivenInteractiveTransition,它遵守
// 在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
推荐阅读
- SpringBoot调用公共模块的自定义注解失效的解决
- python自定义封装带颜色的logging模块
- 列出所有自定义的function和view
- Spring|Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件
- iOS-Swift-map|iOS-Swift-map filter reduce、函数式编程
- 自定义MyAdapter
- Android自定义view实现圆环进度条效果
- Flutter自定义view|Flutter自定义view —— 闯关进度条
- js保留自定义小数点
- django|django 自定义.save()方法