diff --git a/ASDepthModal/ASDepthModalViewController.h b/ASDepthModal/ASDepthModalViewController.h index 27519ab..2eb37e2 100644 --- a/ASDepthModal/ASDepthModalViewController.h +++ b/ASDepthModal/ASDepthModalViewController.h @@ -30,6 +30,11 @@ typedef NS_OPTIONS(NSUInteger, ASDepthModalOptions) { ASDepthModalOptionAnimationGrow = 0 << 0, //default ASDepthModalOptionAnimationShrink = 1 << 0, ASDepthModalOptionAnimationNone = 2 << 0, + ASDepthModalOptionAnimationDropDown = 3 << 0, + + ASDepthModalOptionAnimationCloseShrink = 0 << 4, + ASDepthModalOptionAnimationCloseDropDown = 1 << 4, + ASDepthModalOptionBlur = 0 << 8, // default ASDepthModalOptionBlurNone = 1 << 8, ASDepthModalOptionTapOutsideToClose = 0 << 9, // default @@ -41,8 +46,13 @@ Mostly inspired by http://lab.hakim.se/avgrund/ */ @interface ASDepthModalViewController : UIViewController ++ (void)presentViewController:(UIViewController *)viewController backgroundColor:(UIColor *)color options:(ASDepthModalOptions)options completionHandler:(void(^)())handler; ++ (void)presentViewController:(UIViewController *)viewController; + + (void)presentView:(UIView *)view backgroundColor:(UIColor *)color options:(ASDepthModalOptions)options completionHandler:(void(^)())handler; + (void)presentView:(UIView *)view; + ++ (BOOL)isPresenting; + (void)dismiss; @end diff --git a/ASDepthModal/ASDepthModalViewController.m b/ASDepthModal/ASDepthModalViewController.m index 0fb2e97..96325f0 100644 --- a/ASDepthModal/ASDepthModalViewController.m +++ b/ASDepthModal/ASDepthModalViewController.m @@ -34,16 +34,19 @@ static CGFloat const kDefaultiPadCornerRadius = 6; static NSInteger const kDepthModalOptionAnimationMask = 3 << 0; +static NSInteger const kDepthModalOptionAnimationCloseMask = 3 << 4; static NSInteger const kDepthModalOptionBlurMask = 1 << 8; static NSInteger const kDepthModalOptionTapMask = 1 << 9; @interface ASDepthModalViewController () +@property (nonatomic, strong) UIViewController *viewProvider; @property (nonatomic, strong) UIViewController *rootViewController; @property (nonatomic, strong) UIView *coverView; @property (nonatomic, strong) UIView *popupView; @property (nonatomic, assign) CGAffineTransform initialPopupTransform; @property (nonatomic, strong) UIImageView *blurView; @property (nonatomic, strong) void(^completionHandler)(); +@property (nonatomic) ASDepthModalOptions options; @end @implementation ASDepthModalViewController @@ -72,25 +75,60 @@ - (void)restoreRootViewController - (void)dismiss { - [UIView animateWithDuration:kModalViewAnimationDuration - animations:^{ - self.coverView.alpha = 0; - self.rootViewController.view.transform = CGAffineTransformIdentity; - self.popupView.transform = self.initialPopupTransform; - self.blurView.alpha = 0; - } - completion:^(BOOL finished) { - [self.rootViewController.view.layer setMasksToBounds:NO]; - [self.blurView removeFromSuperview]; - [self restoreRootViewController]; - self.rootViewController.view.layer.cornerRadius = 0; - - if (self.completionHandler) { - self.completionHandler(); - } - }]; + NSInteger style = (self.options & kDepthModalOptionAnimationCloseMask); + + void (^completion)(BOOL) = ^void (BOOL finished){ + [self.rootViewController.view.layer setMasksToBounds:NO]; + [self.blurView removeFromSuperview]; + [self restoreRootViewController]; + self.rootViewController.view.layer.cornerRadius = 0; + + if (self.completionHandler) { + self.completionHandler(); + } + + }; + + switch (style) { + case ASDepthModalOptionAnimationCloseDropDown: + { + CGPoint point = self.popupView.center; + point.y += self.view.bounds.size.height; + [UIView animateWithDuration:0.3 + delay:0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + self.popupView.center = point; + CGFloat angle = ((CGFloat)arc4random_uniform(100) - 50.f) / 100.f; + self.popupView.transform = CGAffineTransformMakeRotation(angle); + + self.coverView.alpha = 0; + self.rootViewController.view.transform = CGAffineTransformIdentity; + // self.popupView.transform = self.initialPopupTransform; + self.blurView.alpha = 0; + } + completion:completion]; + } + break; + default: + case ASDepthModalOptionAnimationCloseShrink: + { + [UIView animateWithDuration:kModalViewAnimationDuration + animations:^{ + self.coverView.alpha = 0; + self.rootViewController.view.transform = CGAffineTransformIdentity; + self.popupView.transform = self.initialPopupTransform; + self.blurView.alpha = 0; + } + completion:completion]; + } + break; + } + } + + - (void)animatePopupWithStyle:(ASDepthModalOptions)options { NSInteger style = (options & kDepthModalOptionAnimationMask); @@ -117,7 +155,17 @@ - (void)animatePopupWithStyle:(ASDepthModalOptions)options }]; } break; - + case ASDepthModalOptionAnimationDropDown: + { + CGFloat y = self.popupView.center.y; + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"]; + animation.values = @[@(y - self.view.bounds.size.height), @(y + 20), @(y - 10), @(y)]; + animation.keyTimes = @[@(0), @(0.5), @(0.75), @(1)]; + animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; + animation.duration = 0.4; + [self.popupView.layer addAnimation:animation forKey:@"dropdown"]; + } + break; default: self.initialPopupTransform = self.popupView.transform; break; @@ -134,6 +182,7 @@ - (void)presentView:(UIView *)view withBackgroundColor:(UIColor *)color options: self.view.backgroundColor = color; } self.completionHandler = handler; + self.options = options; window = [UIApplication sharedApplication].keyWindow; self.rootViewController = window.rootViewController; @@ -243,6 +292,20 @@ - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interf self.rootViewController.view.transform = CGAffineTransformMakeScale(0.9, 0.9); } ++ (void)presentViewController:(UIViewController *)viewController backgroundColor:(UIColor *)color options:(ASDepthModalOptions)options completionHandler:(void(^)())handler +{ + ASDepthModalViewController *modalViewController = [[ASDepthModalViewController alloc] init]; + modalViewController.viewProvider = viewController; + + + [modalViewController presentView:viewController.view withBackgroundColor:(UIColor *)color options:options completionHandler:handler]; +} + ++ (void)presentViewController:(UIViewController *)viewController +{ + [self presentViewController:viewController backgroundColor:nil options:0 completionHandler:nil]; +} + + (void)presentView:(UIView *)view { [self presentView:view backgroundColor:nil options:0 completionHandler:nil]; @@ -275,6 +338,18 @@ + (NSInteger)optionsWithStyle:(ASDepthModalOptions)style blur:(BOOL)blur tapOuts return options; } ++ (BOOL)isPresenting +{ + UIWindow *window; + + window = [UIApplication sharedApplication].keyWindow; + if([window.rootViewController isKindOfClass:[ASDepthModalViewController class]]) + { + return YES; + } + return NO; +} + + (void)dismiss { UIWindow *window; diff --git a/Example/ASDepthModalExample/ASMainViewController.m b/Example/ASDepthModalExample/ASMainViewController.m index 36fba21..d23dae9 100644 --- a/Example/ASDepthModalExample/ASMainViewController.m +++ b/Example/ASDepthModalExample/ASMainViewController.m @@ -21,7 +21,7 @@ @implementation ASMainViewController - (void)setupConfigurations { self.configurationColors = [NSArray arrayWithObjects:@"black (default)", @"pattern", nil]; - self.configurationStyles = [NSArray arrayWithObjects:@"grow (default)", @"shrink", @"none", nil]; + self.configurationStyles = [NSArray arrayWithObjects:@"grow (default)", @"shrink", @"none",@"dropDown", nil]; } - (void)viewDidLoad @@ -75,8 +75,12 @@ - (IBAction)showModalViewAction:(id)sender { style = ASDepthModalOptionAnimationNone; } + else if(styleConfigurationIndex == 3) + { + style = ASDepthModalOptionAnimationDropDown; + } - options = style | (self.blurSwitch.on?ASDepthModalOptionBlur:ASDepthModalOptionBlurNone) | (self.tapOutsideSwitch.on?ASDepthModalOptionTapOutsideToClose:ASDepthModalOptionTapOutsideInactive); + options = style | ASDepthModalOptionAnimationCloseDropDown | (self.blurSwitch.on?ASDepthModalOptionBlur:ASDepthModalOptionBlurNone) | (self.tapOutsideSwitch.on?ASDepthModalOptionTapOutsideToClose:ASDepthModalOptionTapOutsideInactive); [ASDepthModalViewController presentView:self.popupView backgroundColor:color @@ -84,6 +88,7 @@ - (IBAction)showModalViewAction:(id)sender completionHandler:^{ NSLog(@"Modal view closed."); }]; + } - (IBAction)closePopupAction:(id)sender