1、使用
- 新建控制器时继承 GC_Blur_Controller,然后按照正常的modal控制器使用即可。
-
1.1 继承
#import "GC_Blur_Controller.h"
@interface Presented_Controller : GC_Blur_Controller
@end
Presented_Controller *pvc = [[Presented_Controller alloc] init];
pvc.blurStyle = UIBlurEffectStyleLight;
[self presentViewController:pvc animated:YES completion:nil];
2、实现代码
#import <UIKit/UIKit.h>
@interface GC_Blur_Controller : UIViewController
@property(nonatomic, assign) UIBlurEffectStyle blurStyle;
@end
#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