1、使用

  • 新建控制器时继承 GC_Blur_Controller,然后按照正常的modal控制器使用即可。

1.1 继承

#import "GC_Blur_Controller.h"

@interface Presented_Controller : GC_Blur_Controller

@end

1.2 使用

Presented_Controller *pvc = [[Presented_Controller alloc] init];
pvc.blurStyle = UIBlurEffectStyleLight;
[self presentViewController:pvc animated:YES completion:nil];

2、实现代码

2.1 GC_Blur_Controller.h

#import <UIKit/UIKit.h>

@interface GC_Blur_Controller : UIViewController

@property(nonatomic, assign) UIBlurEffectStyle blurStyle;

@end

2.2 GC_Blur_Controller.m

#import "GC_Blur_Controller.h"

@interface GC_Blur_Presenter : NSObject <UIViewControllerTransitioningDelegate>

@property(nonatomic, assign) UIBlurEffectStyle blurStyle;

@end

@class GC_Blur_Presentation_Controller;
@protocol GC_Blur_Presentation_Controller_Delegate <NSObject>

- (void)presentationControllerDidDismissed:(GC_Blur_Presentation_Controller *)controller;

@end

@interface GC_Blur_Presentation_Controller : UIPresentationController

@property(nonatomic, assign) UIBlurEffectStyle blurStyle;

@property(nonatomic, weak) id<GC_Blur_Presentation_Controller_Delegate> gc_delegate;

- (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController
presentingViewController:(UIViewController *)presentingViewController
style:(UIBlurEffectStyle)style;

@end

@interface GC_Blur_Transitioning : NSObject <UIViewControllerAnimatedTransitioning>

@property(nonatomic, assign) BOOL isPresentation;

@end

@interface GC_Blur_Controller ()

@property(nonatomic, strong) GC_Blur_Presenter *presenter;

@end

@implementation GC_Blur_Controller

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self vv_commonSetup];
}
return self;
}

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self vv_commonSetup];
}
return self;
}

- (void)viewDidLoad {
[super viewDidLoad];

self.view.backgroundColor = [UIColor clearColor];
}

- (void)vv_commonSetup {
self.modalPresentationStyle = UIModalPresentationCustom;

_presenter = [[GC_Blur_Presenter alloc] init];
_blurStyle = UIBlurEffectStyleDark;
_presenter.blurStyle = _blurStyle;

self.transitioningDelegate = _presenter;
}

- (void)setBlurStyle:(UIBlurEffectStyle)blurStyle {
if (blurStyle != _blurStyle) {
_blurStyle = blurStyle;
_presenter.blurStyle = blurStyle;
}
}

@end

@interface GC_Blur_Presenter () <GC_Blur_Presentation_Controller_Delegate>

@property(nonatomic, strong) GC_Blur_Presentation_Controller *animationController;

@end

@implementation GC_Blur_Presenter

- (instancetype)init {
self = [super init];
if (self) {
_blurStyle = UIBlurEffectStyleDark;
}
return self;
}

- (GC_Blur_Presentation_Controller *)presentationControllerForPresentedViewController:(UIViewController *)presented
presentingViewController:(UIViewController *)presenting
sourceViewController:(UIViewController *)source {
if (!self.animationController) {
self.animationController = [[GC_Blur_Presentation_Controller alloc] initWithPresentedViewController:presented presentingViewController:presenting style:self.blurStyle];
self.animationController.gc_delegate = self;
}
return self.animationController;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source {

GC_Blur_Transitioning *transition = [[GC_Blur_Transitioning alloc] init];
transition.isPresentation = YES;
return transition;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {

GC_Blur_Transitioning *transition = [[GC_Blur_Transitioning alloc] init];
transition.isPresentation = NO;
return transition;
}

- (void)setBlurStyle:(UIBlurEffectStyle)blurStyle {
if (_blurStyle != blurStyle) {
_blurStyle = blurStyle;
self.animationController.blurStyle = blurStyle;
}
}

- (void)presentationControllerDidDismissed:(GC_Blur_Presentation_Controller *)controller {
self.animationController = nil;
}

@end

@interface GC_Blur_Presentation_Controller ()

@property(nonatomic, strong) UIView *effectContainerView;

@property(nonatomic, strong) UIVisualEffectView *dimmingView;

@end

@implementation GC_Blur_Presentation_Controller

- (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController style:(UIBlurEffectStyle)style {
self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController];
if (self) {
UIBlurEffect *effect = [UIBlurEffect effectWithStyle:style];
_dimmingView = [[UIVisualEffectView alloc] initWithEffect:effect];
_blurStyle = style;
_effectContainerView = [[UIView alloc] init];
_effectContainerView.alpha = 0.0;
}
return self;
}

- (void)presentationTransitionWillBegin {
self.effectContainerView.frame = self.containerView.bounds;
self.dimmingView.frame = self.containerView.bounds;

[self.effectContainerView insertSubview:self.dimmingView atIndex:0];
[self.containerView insertSubview:self.effectContainerView atIndex:0];

self.effectContainerView.alpha = 0.0;

id <UIViewControllerTransitionCoordinator> coordinator = [self.presentedViewController transitionCoordinator];
if (coordinator) {
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
self.effectContainerView.alpha = 1.0;
} completion:nil];
}
else {
self.effectContainerView.alpha = 1.0;
}
}

- (void)dismissalTransitionWillBegin {
id <UIViewControllerTransitionCoordinator> coordinator = [self.presentedViewController transitionCoordinator];
if (coordinator) {
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
self.effectContainerView.alpha = 0.0;
} completion:nil];
}
else {
self.effectContainerView.alpha = 0.0;
}
}

- (void)dismissalTransitionDidEnd:(BOOL)completed {
if (completed) {
if (self.gc_delegate && [self.gc_delegate respondsToSelector:@selector(presentationControllerDidDismissed:)]) {
[self.gc_delegate presentationControllerDidDismissed:self];
}
}
}

- (void)containerViewWillLayoutSubviews {
self.effectContainerView.frame = self.containerView.bounds;
self.dimmingView.frame = self.containerView.bounds;
self.presentedView.frame = self.containerView.bounds;
}

- (BOOL)shouldPresentInFullscreen {
return YES;
}

- (UIModalPresentationStyle)adaptivePresentationStyle {
return UIModalPresentationCustom;
}

- (void)setBlurStyle:(UIBlurEffectStyle)blurStyle {
if (blurStyle != _blurStyle) {
_blurStyle = blurStyle;

UIView *previousDimmingView = _dimmingView;

UIBlurEffect *effect = [UIBlurEffect effectWithStyle:blurStyle];
self.dimmingView = [[UIVisualEffectView alloc] initWithEffect:effect];
NSArray *subviews = [self.effectContainerView subviews];
for (UIView *view in subviews) {
if (view == previousDimmingView) {
self.dimmingView.frame = previousDimmingView.frame;
[self.effectContainerView insertSubview:self.dimmingView aboveSubview:previousDimmingView];
[previousDimmingView removeFromSuperview];
}
}
}
}

@end

@implementation GC_Blur_Transitioning

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 0.5;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

UIView *containerView = [transitionContext containerView];
if (self.isPresentation) {
[containerView addSubview:toView];
}

UIViewController *animatingViewController = self.isPresentation ? toViewController : fromViewController;
UIView *animatingView = self.isPresentation ? toView : fromView;

CGRect onScreenFrame = [transitionContext finalFrameForViewController:animatingViewController];
CGRect offScreenFrame = CGRectOffset(onScreenFrame, 0, onScreenFrame.size.height);

CGRect initialFrame = self.isPresentation ? offScreenFrame : onScreenFrame;
CGRect finalFrame = self.isPresentation ? onScreenFrame : offScreenFrame;
animatingView.frame = initialFrame;

[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 usingSpringWithDamping:300.0 initialSpringVelocity:5.0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{
animatingView.frame = finalFrame;
} completion:^(BOOL finished) {
if (!self.isPresentation) {
[fromView removeFromSuperview];
}
[transitionContext completeTransition:YES];
}];
}

@end


作者:​​ CH520​​