MZBasePresentFadeAnimationVC.h
NS_ASSUME_NONNULL_BEGIN
@interface MZBasePresentFadeAnimationVC : UIViewController
///蒙版
@property (nonatomic, strong) UIView *backgroundView;
///點(diǎn)擊蒙版是否dismiss掉當(dāng)前控制器, 默認(rèn)為YES
@property (nonatomic, assign) BOOL outsideTapDismissEnable;
///dismiss結(jié)束后的回調(diào)
@property (nonatomic, copy) void (^dismissComplete)(void);
@end
NS_ASSUME_NONNULL_END
MZBasePresentFadeAnimationVC.m
#import "MZBasePresentFadeAnimationVC.h"
//MARK: - MZBaseAnimation
@interface MZBaseAnimation : NSObject<UIViewControllerAnimatedTransitioning>
/// present or dismiss
@property (nonatomic, assign, readonly) BOOL isPresenting;
+ (instancetype)alertAnimationIsPresenting:(BOOL)isPresenting;
@end
//MARK: - MZBasePresentFadeAnimationVC
@interface MZBasePresentFadeAnimationVC ()<UIViewControllerTransitioningDelegate>
@property (nonatomic, weak) UITapGestureRecognizer *singleTap;
@end
@implementation MZBasePresentFadeAnimationVC
- (instancetype)init {
if (self = [super init]) {
[self configController];
}
return self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
[self configController];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self addBackgroundView];
[self addSingleTapGesture];
}
- (void)configController {
self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
self.modalPresentationStyle = UIModalPresentationCustom;
self.outsideTapDismissEnable = YES;
self.transitioningDelegate = self;
}
- (void)addBackgroundView {
if (self.backgroundView == nil) {
UIView *backgroundView = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds];
backgroundView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
self.backgroundView = backgroundView;
}
self.backgroundView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view insertSubview:self.backgroundView atIndex:0];
}
- (void)addSingleTapGesture {
self.view.userInteractionEnabled = YES;
self.backgroundView.userInteractionEnabled = YES;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
singleTap.enabled = self.outsideTapDismissEnable;
[self.backgroundView addGestureRecognizer:singleTap];
self.singleTap = singleTap;
}
- (void)onTap:(UITapGestureRecognizer *)tapGesture {
[self dismissViewControllerAnimated:YES];
}
- (void)dismissViewControllerAnimated:(BOOL)animated {
[self dismissViewControllerAnimated:YES completion:self.dismissComplete];
}
@end
@implementation MZBasePresentFadeAnimationVC (TransitionAnimate)
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
return [MZBaseAnimation alertAnimationIsPresenting:YES];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
return [MZBaseAnimation alertAnimationIsPresenting:NO];
}
@end
//MARK: - MZBaseAnimation
@interface MZBaseAnimation ()
@property (nonatomic, assign) BOOL isPresenting;
@end
@implementation MZBaseAnimation
- (instancetype)initWithIsPresenting:(BOOL)isPresenting {
if (self = [super init]) {
self.isPresenting = isPresenting;
}
return self;
}
+ (instancetype)alertAnimationIsPresenting:(BOOL)isPresenting {
return [[self alloc]initWithIsPresenting:isPresenting];
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
if (self.isPresenting) {
return 0.45;
}
return 0.25;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
if (_isPresenting) {
[self presentAnimateTransition:transitionContext];
} else {
[self dismissAnimateTransition:transitionContext];
}
}
- (void)presentAnimateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
MZBasePresentFadeAnimationVC *alertController = (MZBasePresentFadeAnimationVC *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
alertController.backgroundView.alpha = 0.0;
UIView *containerView = [transitionContext containerView];
[containerView addSubview:alertController.view];
[UIView animateWithDuration:0.25 animations:^{
alertController.backgroundView.alpha = 1.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
- (void)dismissAnimateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
MZBasePresentFadeAnimationVC *alertController = (MZBasePresentFadeAnimationVC *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[UIView animateWithDuration:0.25 animations:^{
alertController.backgroundView.alpha = 0.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
@end
使用
只需要將需要模態(tài)出來的VC繼承與MZBasePresentFadeAnimationVC即可。
- (IBAction)show:(id)sender {
DetailViewController *vc = [[DetailViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}