iOS实现类似格瓦拉电影的转场动画

2020-01-18 16:52:49王冬梅

用过格瓦拉电影,或者其他app可能都知道,一种点击按钮用放大效果实现转场的动画现在很流行,效果大致如下

ios,格瓦拉动画效果,转场动画,push转场动画

自定义转场动画

首先就要声明一个遵守UIViewControllerAnimatedTransitioning协议的类.

然后实现协议中的两个函数


// This is used for percent driven interactive transitions, as well as for container controllers that have companion animations that might need to
// 返回转场时间
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
// 转场的动作
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

push和pop都在animateTransition:里面实现,所以需要一个参数表示是push还是pop;还有一个参数表示转场时间


#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>


typedef enum : NSUInteger {
 animate_push = 0,
 animate_pop = 1,

} Animate_Type;

@interface SFTrainsitionAnimate : NSObject<UIViewControllerAnimatedTransitioning>

- (instancetype)initWithAnimateType:(Animate_Type)type andDuration:(CGFloat)dura;

@property (assign, nonatomic) CGFloat duration;
@property (assign, nonatomic) Animate_Type type;

@end

那么要如何使用新建的对象呢?可以通过UINavigationControllerDelegate中的


- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
 if (operation == UINavigationControllerOperationPush) {
 self.animate = [[SFTrainsitionAnimate alloc] init];
 return self.animate;
 }else{
 return nil;
 }

}

当然,要调用这个方法还得先把UINavigationControllerDelegate委托给视图控制器


self.navigationController.delegate = self;

再来看看UIViewControllerAnimatedTransitioning这个协议,返回时间的方法就不介绍了。重点在


- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
 //起始视图控制器
 UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
 //目标视图控制器
 UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
 //在这个视图上实现跳转动画
 UIView *containView = [transitionContext containerView];
}

如上注释,我们可以通过参数