LBModalTool
原理
创建一个对象,设置为VC的transitioningDelegate ,遵守UIViewControllerTransitioningDelegate 协议,并实现相应的方法,
再创建一个类, 遵循UIViewControllerAnimatedTransitioning 协议,并实现相应的方法
实现代码
///LBModalConfiguration.h
typedef void(^LBViewControllerPresentAndDismissCompletionBlock)(void);
typedef void(^LBViewControllerPresentAndDismissBlock)(LBViewControllerPresentAndDismissCompletionBlock completion);
@interface LBModalConfiguration : NSObject <UIViewControllerAnimatedTransitioning>
- (instancetype)initWithType:(NSString *)type duration:(CGFloat)duration;
// type
// - present
// - dismiss
@property (copy, nonatomic) NSString * type;
// duration
@property (assign, nonatomic) CGFloat duration;
// blockPresentAndDismiss
@property (copy, nonatomic) LBViewControllerPresentAndDismissBlock presentAndDismiss;
@end
//LBModalConfiguration.m
@implementation LBModalConfiguration
- (instancetype)initWithType:(NSString *)type duration:(CGFloat)duration
{
if (self = [super init]) {
self.type = type;
self.duration = duration;
}
return self;
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return self.duration;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIView * from = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView * to = [transitionContext viewForKey:UITransitionContextToViewKey];
if ([self.type isEqualToString:@"present"]) {
[transitionContext.containerView addSubview:to];
}
self.presentAndDismiss(^{
if ([self.type isEqualToString:@"dismiss"]) {
[from removeFromSuperview];
}
[transitionContext completeTransition:true];
});
}
@end
//LBModalTool.h
@interface LBModalTool : NSObject <UIViewControllerTransitioningDelegate>
/**
自定义弹出动画代理
@param viewController 弹出的控制器
@param duration 动画时长
@param present 动画过程
@param dismiss 动画结束回调
@return 动画代理(自身)
*/
- (instancetype)initWithViewController:(UIViewController *)viewController
duration:(CGFloat)duration
present:(LBViewControllerPresentAndDismissBlock)present dismiss:(LBViewControllerPresentAndDismissBlock)dismiss;
//LBModalTool.m
@interface LBModalTool ()
@property (weak, nonatomic) UIViewController * viewController;
@property (assign, nonatomic) CGFloat duration;
@property (copy, nonatomic) LBViewControllerPresentAndDismissBlock present;
@property (copy, nonatomic) LBViewControllerPresentAndDismissBlock dismiss;
@end
@implementation LBModalTool
- (instancetype)initWithViewController:(UIViewController *)viewController duration:(CGFloat)duration present:(LBViewControllerPresentAndDismissBlock)present dismiss:(LBViewControllerPresentAndDismissBlock)dismiss
{
if (self = [super init]) {
self.viewController = viewController;
[self setTDViewControllerPresentAndDismiss];
self.duration = duration;
self.present = present;
self.dismiss = dismiss;
}
return self;
}
- (void)setTDViewControllerPresentAndDismiss
{
self.viewController.transitioningDelegate = self;
self.viewController.modalPresentationStyle = UIModalPresentationCustom;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
LBModalConfiguration * present = [[LBModalConfiguration alloc] initWithType:@"present" duration:self.duration];
present.presentAndDismiss = ^(void (^block)(void)) {
self.present(^{
block();
});
};
return present;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
LBModalConfiguration * dismiss = [[LBModalConfiguration alloc] initWithType:@"dismiss" duration:self.duration];
dismiss.presentAndDismiss = ^(void (^block)(void)) {
self.dismiss(^{
block();
});
};
return dismiss;
}
使用方法
pod 'LBModalTool'
@interface LBPresentedViewController ()
@property (nonatomic, strong) LBModalTool *modalTool;
@property (nonatomic, strong) UIView *whiteView;
@end
@implementation LBPresentedViewController
- (instancetype)init
{
if (self = [super init]) {
__weak typeof(self) weakSelf = self;
self.modalTool = [[LBModalTool alloc] initWithViewController:self
duration:0.5
present:^(LBViewControllerPresentAndDismissCompletionBlock completion)
{
[UIView animateWithDuration:0.3 animations:^{
weakSelf.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
weakSelf.whiteView.frame = CGRectMake(0, 100, CGRectGetWidth(weakSelf.view.bounds), CGRectGetHeight(weakSelf.view.bounds) - 100);
[weakSelf.view layoutIfNeeded];
} completion:^(BOOL finished) {
completion();
}];
} dismiss:^(LBViewControllerPresentAndDismissCompletionBlock completion) {
[UIView animateWithDuration:0.3 animations:^{
weakSelf.view.backgroundColor = [UIColor clearColor];
weakSelf.whiteView.frame = CGRectMake(0, CGRectGetHeight(weakSelf.view.bounds), CGRectGetWidth(weakSelf.view.bounds), CGRectGetHeight(weakSelf.view.bounds) - 100);
[weakSelf.view layoutIfNeeded];
} completion:^(BOOL finished) {
completion();
}];
}];
}
return self;
}