iOS 转场动画
2018-05-26 本文已影响42人
觞咏畅情
model类型的转场动画系统默认提供了4个
UIModalTransitionStyleCoverVertical, //垂直上入(默认)
UIModalTransitionStyleFlipHorizontal, //水平反转
UIModalTransitionStyleCrossDissolve, //渐显效果
UIModalTransitionStylePartialCurl //翻页效果
//使用方式
QMoreViewController *moreVC = [[QMoreViewController alloc] init];
moreVC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
moreVC.transitioningDelegate = animation;
[self presentViewController:moreVC animated:YES completion:nil}];
自定义的话 建议构造一个转场对象,具体如下
QTranstionAnimation
对象
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, QTranstionAnimationType) {
QTranstionAnimationType_FromTop, //上进上出
QTranstionAnimationType_FadeInOut //淡入淡出
};
@interface QTranstionAnimation : NSObject<UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning>
//初始化
+(instancetype)shareInstance;
/**
动画类型
*/
@property (nonatomic, assign) QTranstionAnimationType animatType;
@end
#import "QTranstionAnimation.h"
#import "QPresentationController.h"
static QTranstionAnimation *transtion = nil;
@interface QTranstionAnimation()
@property (nonatomic, assign) BOOL isPresnted;
@end;
@implementation QTranstionAnimation
//构造单例
+(instancetype)shareInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
transtion = [[super allocWithZone:nil] init];
});
return transtion;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone{
return [QTranstionAnimation shareInstance];
}
- (id)copyWithZone:(struct _NSZone *)zone {
return [QTranstionAnimation shareInstance];
}
#pragma mark - UIViewControllerContextTransitioning
- (void)animateTransition:(nonnull id<UIViewControllerContextTransitioning>)transitionContext {
if (self.isPresnted == YES) {
//1.取出view
UIView *presentedView = [transitionContext viewForKey:UITransitionContextToViewKey];
//2.放入containerView
[[transitionContext containerView] addSubview:presentedView];
//3.自定义添加动画
if(self.animatType == QTranstionAnimationType_FromTop){
presentedView.frame = CGRectMake(0, -kScreenH, kScreenW, kScreenH);
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
presentedView.frame = CGRectMake(0, 0, kScreenW, kScreenH);
}completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}else if(self.animatType == QTranstionAnimationType_FadeInOut){
presentedView.alpha = 0;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
presentedView.alpha = 1.0;
}completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
} else {
//1.取出view
UIView *dismissedView = [transitionContext viewForKey:UITransitionContextFromViewKey];
//2.放入containerView
[[transitionContext containerView]addSubview:dismissedView];
//3.自定义添加动画
if(self.animatType == QTranstionAnimationType_FromTop){
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
dismissedView.frame =CGRectMake(0, -kScreenH, kScreenW, kScreenH);
}completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}else if (self.animatType == QTranstionAnimationType_FadeInOut){
dismissedView.alpha = 1;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
dismissedView.alpha = 0;
}completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
}
}
- (NSTimeInterval)transitionDuration:(nullable id<UIViewControllerContextTransitioning>)transitionContext {
return 0.5f;
}
#pragma mark - UIViewControllerTransitioningDelegate
//设置负责进场的对象
-(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
self.isPresnted = YES;
return self;
}
//设置负责出场的对象
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
self.isPresnted = NO;
return self;
}
//以下两个方法负责交互处理
//- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator;
//- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator;
//该方法为对容器的处理
- (nullable UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(nullable UIViewController *)presenting sourceViewController:(UIViewController *)source NS_AVAILABLE_IOS(8_0){
QPresentationController *persentVC = [[QPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
persentVC.contentFrame = CGRectMake((kScreenW-300)/2, (kScreenH-400)/2, 300, 400);
return persentVC;
}
@end
自定义容器为
QPresentationController
#import "QPresentationController.h"
@interface QPresentationController()
@property (nonatomic, strong) UIView *coverView;//蒙板
@end
@implementation QPresentationController
-(void)containerViewWillLayoutSubviews{
[super containerViewWillLayoutSubviews];
self.presentedView.frame = self.contentFrame;
[self.containerView insertSubview:self.coverView atIndex:0];
}
-(void)didMissAction{
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
}
-(UIView *)coverView{
if(!_coverView){
_coverView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_coverView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:0.3];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didMissAction)];
[_coverView addGestureRecognizer:tap];
}
return _coverView;
}
@end
最后 具体使用
QTranstionAnimation *animation = [QTranstionAnimation shareInstance];
QMoreViewController *moreVC = [[QMoreViewController alloc] init];
moreVC.modalPresentationStyle = UIModalPresentationCustom;
moreVC.transitioningDelegate = animation;
[self presentViewController:moreVC animated:YES completion:^{
}];