From 042847a51482fd25bf123b7030afe8199a60d732 Mon Sep 17 00:00:00 2001 From: yulingtianxia Date: Sat, 12 Jan 2019 19:47:22 +0800 Subject: [PATCH] 1.7.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 支持自定义动画 2. 优化 API --- .../TBAlertControllerDemo/ViewController.m | 20 ++- README.md | 157 +----------------- Source/TBActionSheet/TBActionButton.h | 24 ++- Source/TBActionSheet/TBActionButton.m | 10 +- Source/TBActionSheet/TBActionSheet.h | 35 +++- Source/TBActionSheet/TBActionSheet.m | 115 ++++++++----- Source/TBActionSheet/UIWindow+TBAdditions.m | 12 +- Source/Utils/TBMacro.h | 5 +- TBActionSheet.podspec | 4 +- 9 files changed, 165 insertions(+), 217 deletions(-) diff --git a/Example/TBAlertControllerDemo/ViewController.m b/Example/TBAlertControllerDemo/ViewController.m index 286c9a8..caca0e9 100644 --- a/Example/TBAlertControllerDemo/ViewController.m +++ b/Example/TBAlertControllerDemo/ViewController.m @@ -66,13 +66,23 @@ - (IBAction)clickActionSheet:(UIButton *)sender { // [addBtn addTarget:self action:@selector(addButton:) forControlEvents:UIControlEventTouchUpInside]; // self.actionSheet.customView = addBtn; + TBActionButton *destructiveBtn = [self.actionSheet buttonAtIndex:self.actionSheet.destructiveButtonIndex]; + destructiveBtn.animation = ^(UIImageView * _Nonnull background, UIView * _Nonnull container, void (^ _Nonnull completion)(void)) { + [UIView animateWithDuration:0.5 animations:^{ + background.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; + container.frame = CGRectMake(CGRectGetMidX(container.frame), CGRectGetMidY(container.frame), 0, 0); + } completion:^(BOOL finished) { + completion(); + }]; + }; + __weak __typeof(ViewController *) weakSelf = self; [self.actionSheet addButtonWithTitle:@"支持 block" style:TBActionButtonStyleCancel handler:^(TBActionButton * _Nonnull button) { NSLog(@"%@ %@",button.currentTitle,weakSelf.leakTest); }]; - TBActionButton *btn = [self.actionSheet buttonAtIndex:self.actionSheet.numberOfButtons - 1]; - btn.normalColor = [UIColor yellowColor]; - btn.highlightedColor = [UIColor greenColor]; + TBActionButton *blockBtn = [self.actionSheet buttonAtIndex:self.actionSheet.numberOfButtons - 1]; + blockBtn.normalColor = [UIColor yellowColor]; + blockBtn.highlightedColor = [UIColor greenColor]; //创建NSMutableAttributedString NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:@"支持 block\n限时推广"]; @@ -83,8 +93,8 @@ - (IBAction)clickActionSheet:(UIButton *)sender { [attrStr addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, 9)]; [attrStr addAttribute:NSForegroundColorAttributeName value:[UIColor grayColor] range:NSMakeRange(9, 4)]; - [btn setAttributedTitle:attrStr forState:UIControlStateNormal]; - btn.height = 70; + [blockBtn setAttributedTitle:attrStr forState:UIControlStateNormal]; + blockBtn.height = 70; [self.actionSheet show]; [self.conditioner setUpUI]; } diff --git a/README.md b/README.md index 8aac5a4..259e443 100755 --- a/README.md +++ b/README.md @@ -22,15 +22,14 @@ Here are some pictures showing TBActionSheet's powerful individuation. You can c ![](images/demo.gif) ![](images/addButton.gif) -**TBActionSheet supports autorotation**, but there is some bugs on iOS7 :( - -BTW, `TBActionSheet` also suppots BLOCK now! +BTW, `TBActionSheet` also supports **CUSTOM ANIMATION**! ## 🌟 Feature - [x] Title - [x] Description message - [x] Insert a custom view at anywhere +- [x] Custom animation. - [x] Customizations: fonts, colors, dimensions, corners & more - [x] Closure when a button or background is pressed - [x] Similar implementation to UIActionSheet @@ -38,7 +37,7 @@ BTW, `TBActionSheet` also suppots BLOCK now! - [x] Scroll the whole action sheet. - [x] Blur Effect under iOS7 - [x] Autorotation under iOS8 -- [x] Cocoapods +- [x] CocoaPods - [x] Carthage ## 📚 Article @@ -52,8 +51,8 @@ To run the example project, clone the repo and run MTDemo target. ## 💰 Requirement -- iOS 6.0+ (iOS 8.0+ full features supported) -- Xcode 9.1+ +- iOS 7.0+ (iOS 8.0+ full features supported) +- Xcode 10.1+ ## 📲 Installation @@ -124,149 +123,9 @@ rectCornerRadius = 0; ### More than what you want -The base usage is same to `UIActionSheet`. You can just replace `UIActionSheet` with `TBActionSheet`. If you want to customize your action sheet, just configure some properties. I believe the header file can tell you much more than me. +The base usage is same to `UIActionSheet`. You can just replace `UIActionSheet` with `TBActionSheet`. If you want to customize your action sheet, just configure some properties. -``` -@interface TBActionSheet : UIView -@property(nullable,nonatomic,weak) id delegate; -@property(nullable,nonatomic,copy) NSString *title; -@property(nullable,nonatomic,copy) NSString *message; -/** - * 标记藏于 ActionSheet 下面的 UIWindow - */ -@property (weak, nonatomic, readonly) UIWindow *previousKeyWindow; - -- (instancetype)initWithTitle:(nullable NSString *)title delegate:(nullable id )delegate cancelButtonTitle:(nullable NSString *)cancelButtonTitle destructiveButtonTitle:(nullable NSString *)destructiveButtonTitle otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; -- (instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id )delegate cancelButtonTitle:(nullable NSString *)cancelButtonTitle destructiveButtonTitle:(nullable NSString *)destructiveButtonTitle otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; -- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE; - -// adds a button with the title. returns the index (0 based) of where it was added. buttons are displayed in the order added except for the -// destructive and cancel button which will be positioned based on HI requirements. buttons cannot be customized. -- (NSInteger)addButtonWithTitle:(nullable NSString *)title; -- (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style; // returns index of button. 0 based. -- (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style handler:(nullable void (^)(TBActionButton * button))handler; -- (nullable NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex; -- (nullable TBActionButton *)buttonAtIndex:(NSInteger)buttonIndex; -@property(nonatomic,readonly) NSInteger numberOfButtons; -@property(nonatomic) NSInteger cancelButtonIndex; // if the delegate does not implement -actionSheetCancel:, we pretend this button was clicked on. default is -1 -@property(nonatomic) NSInteger destructiveButtonIndex; // sets destructive (red) button. -1 means none set. default is -1. ignored if only one button - -@property(nonatomic,readonly) NSInteger firstOtherButtonIndex; // -1 if no otherButtonTitles or initWithTitle:... not used -/** - 自定义视图在按钮中插入的 Index,值在 [0...numberOfButtons] 之间。如果 customView 为 nil,则 customViewIndex 值为 -1 - */ -@property(nonatomic) NSInteger customViewIndex; -/** - * 是否可见 - */ -@property(nonatomic,readonly,getter=isVisible) BOOL visible; - -/** - * 显示 ActionSheet - */ -- (void)show; -/** - * 显示 ActionSheet,已废弃 - * - * @param view 此参数直接传 nil - */ -- (void)showInView:(nullable UIView *)view __deprecated; - -//custom UI -/** - * 按钮高度 - */ -@property(nonatomic) CGFloat buttonHeight UI_APPEARANCE_SELECTOR; -/** - * actionsheet下方的 y 轴位移,向下为正,非负值无效,默认值为 -8 - */ -@property(nonatomic) CGFloat offsetY UI_APPEARANCE_SELECTOR; -/** - * 标题 UILabel - */ -@property(nonatomic,strong,nullable,readonly) UILabel *titleLabel; -/** - * Message UILabel - */ -@property(nonatomic,strong,nullable,readonly) UILabel *messageLabel; -/** - * 文字颜色 - */ -@property(nonatomic,strong) UIColor *tintColor UI_APPEARANCE_SELECTOR; -/** - * Destructive 按钮文字颜色 - */ -@property(nonatomic,strong) UIColor *destructiveButtonColor UI_APPEARANCE_SELECTOR; -/** - * Cancel 按钮文字颜色 - */ -@property(nonatomic,strong) UIColor *cancelButtonColor UI_APPEARANCE_SELECTOR; -/** - * 分割线颜色 - */ -@property(nonatomic,strong) UIColor *separatorColor UI_APPEARANCE_SELECTOR; -/** - * 按钮字体 - */ -@property(nonatomic,strong) UIFont *buttonFont UI_APPEARANCE_SELECTOR; -/** - * sheet 的宽度,也就是按钮宽度 - */ -@property(nonatomic) CGFloat sheetWidth UI_APPEARANCE_SELECTOR; -/** - * 是否让 ActionSheet 背景透明 - */ -@property(nonatomic, getter=isBackgroundTransparentEnabled) NSInteger backgroundTransparentEnabled UI_APPEARANCE_SELECTOR; -/** - * 是否点击背景后关闭 ActionSheet - */ -@property(nonatomic, getter=isBackgroundTouchClosureEnabled) NSInteger backgroundTouchClosureEnabled UI_APPEARANCE_SELECTOR; -/** - * 是否启用毛玻璃效果 - */ -@property(nonatomic, getter=isBlurEffectEnabled) NSInteger blurEffectEnabled UI_APPEARANCE_SELECTOR; -/** - * 矩形圆角半径 - */ -@property(nonatomic,assign) CGFloat rectCornerRadius UI_APPEARANCE_SELECTOR; -/** - * ActionSheet 的环境色 - */ -@property(nonatomic,strong) UIColor *ambientColor UI_APPEARANCE_SELECTOR; -/** - * 自定义视图 - */ -@property(nonatomic,strong,nullable) UIView *customView; -/** - * 动画持续时长 - */ -@property(nonatomic,assign) NSTimeInterval animationDuration UI_APPEARANCE_SELECTOR; -/** - * 动画弹簧效果衰弱比例,值为 1 时无摆动,值越接近 0 摆动越大 - */ -@property(nonatomic,assign) CGFloat animationDampingRatio UI_APPEARANCE_SELECTOR; -/** - * 动画弹簧效果初速度。如果动画总距离为 200 点,想让初速度为每秒 100 点,那么将值设为 0.5 - */ -@property(nonatomic,assign) CGFloat animationVelocity UI_APPEARANCE_SELECTOR; -/** - * 支持的朝向 - */ -@property(nonatomic,assign) UIInterfaceOrientationMask supportedInterfaceOrientations UI_APPEARANCE_SELECTOR; -/** - * 设置布局 - */ -- (void)setupLayout; -/** - * 设置毛玻璃效果、圆角、背景颜色等风格 - */ -- (void)setupStyle; -/** - * 设置容器 frame - */ -- (void)setupContainerFrame; -@end -``` +[GitHub wiki](https://github.com/yulingtianxia/TBActionSheet/wiki) can help you master advanced usage. There is also an example project for `TBActionSheet`. @@ -291,8 +150,6 @@ TBAlertAction *cancel = [TBAlertAction actionWithTitle:@"取消" style: TBAlertA [self presentViewController:controller animated:YES completion:nil]; ``` - - For more infomation about `TBAlertController`, please visit [this post](http://yulingtianxia.com/blog/2015/11/13/Summary-of-the-first-month-in-the-internship-of-Tencent/) of my blog. ## ❤️ Contributed diff --git a/Source/TBActionSheet/TBActionButton.h b/Source/TBActionSheet/TBActionButton.h index 5b367bb..e671161 100644 --- a/Source/TBActionSheet/TBActionButton.h +++ b/Source/TBActionSheet/TBActionButton.h @@ -16,12 +16,31 @@ typedef NS_ENUM(NSInteger, TBActionButtonStyle) { TBActionButtonStyleDestructive, }; + +/** + 自定义动画 Block + + @param background 全屏背景视图,可用做阴影渐变等动画 + @param container ActionSheet 容器视图,可设置 frame 等做动画。做 show 动画时,建议调用 updateContainerFrame 方法来设定动画的结束 frame(而不是手动随便设个 frame)。 + @param ^completion 动画结束的回调 block,一定要调用。 + */ +typedef void(^TBActionSheetAnimation)(UIImageView *background, UIView *container, void(^completion)(void)); +@class TBActionButton; +typedef void(^TBActionButtonHandler)(TBActionButton * button); + @interface TBActionButton : UIButton @property (nonatomic, nullable) UIColor *normalColor; @property (nonatomic, nullable) UIColor *highlightedColor; @property (nonatomic) TBActionButtonStyle style; -@property (nonatomic, nullable, strong, readonly) void (^handler)(TBActionButton * button); +/** + 点击按钮后的响应回调 + */ +@property (nonatomic, nullable, strong, readonly) TBActionButtonHandler handler; +/** + 点击按钮后 TBActionSheet 的自定义关闭动画 + */ +@property (nonatomic, nullable, strong) TBActionSheetAnimation animation; /** * 位于按钮后面的调节颜色的图层,在没有 `normalColor` 或 `highlightedColor` 时使用 ambientColor 替代 */ @@ -29,7 +48,8 @@ typedef NS_ENUM(NSInteger, TBActionButtonStyle) { @property (nonatomic) CGFloat height; + (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style; -+ (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style handler:(nullable void (^)(TBActionButton * button))handler; ++ (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style handler:(nullable TBActionButtonHandler)handler; ++ (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style handler:(nullable TBActionButtonHandler)handler animation:(nullable TBActionSheetAnimation)animation; @end diff --git a/Source/TBActionSheet/TBActionButton.m b/Source/TBActionSheet/TBActionButton.m index a6d3a8a..c9be36c 100644 --- a/Source/TBActionSheet/TBActionButton.m +++ b/Source/TBActionSheet/TBActionButton.m @@ -22,14 +22,20 @@ @implementation TBActionButton + (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style { - return [TBActionButton buttonWithTitle:title style:style handler:nil]; + return [self buttonWithTitle:title style:style handler:nil]; } -+ (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style handler:(nullable void (^)(TBActionButton * button))handler ++ (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style handler:(nullable TBActionButtonHandler)handler +{ + return [self buttonWithTitle:title style:style handler:handler animation:nil]; +} + ++ (instancetype)buttonWithTitle:(NSString *)title style:(TBActionButtonStyle)style handler:(nullable TBActionButtonHandler)handler animation:(nullable TBActionSheetAnimation)animation { TBActionButton *button = [TBActionButton buttonWithType:UIButtonTypeCustom]; button.style = style; button.handler = handler; + button.animation = animation; button.clipsToBounds = YES; [button setTitle:title forState:UIControlStateNormal]; [button setBackgroundColor:[UIColor clearColor]]; diff --git a/Source/TBActionSheet/TBActionSheet.h b/Source/TBActionSheet/TBActionSheet.h index d977e34..40af259 100644 --- a/Source/TBActionSheet/TBActionSheet.h +++ b/Source/TBActionSheet/TBActionSheet.h @@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol TBActionSheetDelegate; @interface TBActionSheet : UIView + @property (nullable, nonatomic, weak) id delegate; @property (nullable, nonatomic, copy) NSString *title; @property (nullable, nonatomic, copy) NSString *message; @@ -31,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN - (NSInteger)addButtonWithTitle:(nullable NSString *)title; - (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style; // returns index of button. 0 based. - (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style handler:(nullable void (^)(TBActionButton * button))handler; +- (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style handler:(nullable TBActionButtonHandler)handler animation:(nullable TBActionSheetAnimation)animation; - (nullable NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex; - (nullable TBActionButton *)buttonAtIndex:(NSInteger)buttonIndex; @property (nonatomic, readonly) NSInteger numberOfButtons; @@ -52,6 +54,12 @@ NS_ASSUME_NONNULL_BEGIN * 显示 ActionSheet */ - (void)show; +/** + 使用自定义动画显示 ActionSheet + + @param animation 自定义动画,传 nil 则等价于 show 方法,使用默认动画。 + */ +- (void)showWithAnimation:(nullable TBActionSheetAnimation)animation; /** * 显示 ActionSheet,已废弃 * @@ -60,9 +68,20 @@ NS_ASSUME_NONNULL_BEGIN - (void)showInView:(nullable UIView *)view __deprecated; /** - * 取消 ActionSheet 的方法 + 关闭动画,不设置则为默认动画。 + NOTE: 设置 nil 是无效的。 + */ +@property (nonatomic, strong) TBActionSheetAnimation closeAnimation; +/** + * 关闭 ActionSheet 的方法 */ - (void)close; +/** + 使用自定义动画关闭 ActionSheet + + @param animation 自定义动画,传 nil 则等价于 close 方法,使用 closeAnimation。 + */ +- (void)closeWithAnimation:(nullable TBActionSheetAnimation)animation; //custom UI /** @@ -108,15 +127,15 @@ NS_ASSUME_NONNULL_BEGIN /** * 是否让 ActionSheet 背景透明 */ -@property (nonatomic, getter=isBackgroundTransparentEnabled) NSInteger backgroundTransparentEnabled UI_APPEARANCE_SELECTOR; +@property (nonatomic, getter=isBackgroundTransparentEnabled) BOOL backgroundTransparentEnabled UI_APPEARANCE_SELECTOR; /** * 是否点击背景后关闭 ActionSheet */ -@property (nonatomic, getter=isBackgroundTouchClosureEnabled) NSInteger backgroundTouchClosureEnabled UI_APPEARANCE_SELECTOR; +@property (nonatomic, getter=isBackgroundTouchClosureEnabled) BOOL backgroundTouchClosureEnabled UI_APPEARANCE_SELECTOR; /** * 是否启用毛玻璃效果 */ -@property (nonatomic, getter=isBlurEffectEnabled) NSInteger blurEffectEnabled UI_APPEARANCE_SELECTOR; +@property (nonatomic, getter=isBlurEffectEnabled) BOOL blurEffectEnabled UI_APPEARANCE_SELECTOR; /** * 矩形圆角半径 */ @@ -130,15 +149,15 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, strong, nullable) UIView *customView; /** - * 动画持续时长 + * 默认动画的持续时长 */ @property (nonatomic, assign) NSTimeInterval animationDuration UI_APPEARANCE_SELECTOR; /** - * 动画弹簧效果衰弱比例,值为 1 时无摆动,值越接近 0 摆动越大 + * 默认动画的动画弹簧效果衰弱比例,值为 1 时无摆动,值越接近 0 摆动越大 */ @property (nonatomic, assign) CGFloat animationDampingRatio UI_APPEARANCE_SELECTOR; /** - * 动画弹簧效果初速度。如果动画总距离为 200 点,想让初速度为每秒 100 点,那么将值设为 0.5 + * 默认动画的动画弹簧效果初速度。如果动画总距离为 200 点,想让初速度为每秒 100 点,那么将值设为 0.5 */ @property (nonatomic, assign) CGFloat animationVelocity UI_APPEARANCE_SELECTOR; /** @@ -174,7 +193,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)setupStyle; /** - * 设置容器 frame + * 更新容器展示在屏幕上的 frame */ - (void)updateContainerFrame; @end diff --git a/Source/TBActionSheet/TBActionSheet.m b/Source/TBActionSheet/TBActionSheet.m index 5e3b540..057180e 100644 --- a/Source/TBActionSheet/TBActionSheet.m +++ b/Source/TBActionSheet/TBActionSheet.m @@ -93,6 +93,21 @@ - (instancetype)init _cancelButtonIndex = -1; _destructiveButtonIndex = -1; _windowLevel = UIWindowLevelStatusBar + 100; + TBWeakSelf(self); + _closeAnimation = ^(UIImageView * _Nonnull background, UIView * _Nonnull container, void (^ _Nonnull completion)(void)) { + TBStrongSelf(self); + void(^animations)(void) = ^() { + background.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; + container.frame = CGRectMake(kContainerLeft, kScreenHeight, container.frame.size.width, container.frame.size.height); + }; + [UIView animateWithDuration:self.animationDuration + delay:0 + options:UIViewAnimationOptionCurveEaseInOut + animations:animations + completion:^(BOOL finished) { + completion(); + }]; + }; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarDidChangeOrientation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; } return self; @@ -160,9 +175,14 @@ - (NSInteger)addButtonWithTitle:(NSString *)title style:(TBActionButtonStyle)sty return [self addButtonWithTitle:title style:style handler:nil]; } -- (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style handler:(nullable void (^)( TBActionButton * button))handler +- (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style handler:(nullable TBActionButtonHandler)handler { - TBActionButton *button = [TBActionButton buttonWithTitle:title style:style handler:handler]; + return [self addButtonWithTitle:title style:style handler:handler animation:nil]; +} + +- (NSInteger)addButtonWithTitle:(nullable NSString *)title style:(TBActionButtonStyle)style handler:(nullable TBActionButtonHandler)handler animation:(TBActionSheetAnimation)animation +{ + TBActionButton *button = [TBActionButton buttonWithTitle:title style:style handler:handler animation:animation]; [button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]; [self.buttons addObject:button]; NSInteger index = self.buttons.count - 1; @@ -254,7 +274,7 @@ - (BOOL)isVisible return !!self.window && self.window.rootViewController; } -- (void)setBackgroundTouchClosureEnabled:(NSInteger)backgroundTouchClosureEnabled +- (void)setBackgroundTouchClosureEnabled:(BOOL)backgroundTouchClosureEnabled { _backgroundTouchClosureEnabled = backgroundTouchClosureEnabled; self.background.userInteractionEnabled = backgroundTouchClosureEnabled; @@ -266,6 +286,14 @@ - (void)setScrollEnabled:(BOOL)scrollEnabled self.scrollView.scrollEnabled = scrollEnabled; } +- (void)setCloseAnimation:(TBActionSheetAnimation)closeAnimation +{ + if (!closeAnimation) { + return; + } + _closeAnimation = closeAnimation; +} + #pragma mark - show action /** * 设定新的 UIWindow,并将 TBActionSheet 附加在上面 @@ -303,16 +331,8 @@ - (void)setupLayout //获取当前文本的属性 NSDictionary * tdic = @{NSFontAttributeName:label.font}; CGSize actualsize; - if (kiOS7Later) { - //iOS7方法,获取文本需要的size,限制宽度 - actualsize =[content boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:tdic context:nil].size; - } - else { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - actualsize = [content sizeWithFont:label.font]; -#pragma GCC diagnostic pop - } + //iOS7方法,获取文本需要的size,限制宽度 + actualsize =[content boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:tdic context:nil].size; label.frame = CGRectMake(0, lastY, self.sheetWidth, actualsize.height); lastY = CGRectGetMaxY(label.frame); }; @@ -658,7 +678,7 @@ - (void)refreshBlurEffect - (void)updateContainerFrame { - CGFloat y = kScreenHeight - self.actionContainer.frame.size.height - (!kiOS7Later? 20: 0); + CGFloat y = kScreenHeight - self.actionContainer.frame.size.height; self.scrollView.frame = CGRectMake(kContainerLeft, MAX(0, y), self.scrollView.frame.size.width, MIN(self.actionContainer.frame.size.height, kScreenHeight)); self.scrollView.contentOffset = CGPointMake(0, MAX(0, -y)); } @@ -666,6 +686,12 @@ - (void)updateContainerFrame * 显示 ActionSheet */ - (void)show +{ + //弹出 ActionSheet 动画 + [self showWithAnimation:nil]; +} + +- (void)showWithAnimation:(TBActionSheetAnimation)animation { if ([self.delegate respondsToSelector:@selector(willPresentAlertView:)]) { [self.delegate willPresentActionSheet:self]; @@ -677,23 +703,31 @@ - (void)show [self setupStyle]; - //弹出 ActionSheet 动画 - void(^animations)(void) = ^() { - self.background.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; - [self updateContainerFrame]; - }; - void(^completion)(BOOL finished) = ^(BOOL finished) { + void(^completion)(void) = ^() { if ([self.delegate respondsToSelector:@selector(didPresentActionSheet:)]) { [self.delegate didPresentActionSheet:self]; } self.visible = YES; }; - if (kiOS7Later) { - [UIView animateWithDuration:self.animationDuration delay:0 usingSpringWithDamping:self.animationDampingRatio initialSpringVelocity:self.animationVelocity options:UIViewAnimationOptionCurveEaseInOut animations:animations completion:completion]; - } - else { - [UIView animateWithDuration:self.animationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:animations completion:completion]; - } + // 使用内置动画 + if (!animation) { + animation = ^(UIImageView * _Nonnull background, UIView * _Nonnull container, void (^ _Nonnull completion)(void)) { + void(^animations)(void) = ^() { + background.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; + [self updateContainerFrame]; + }; + [UIView animateWithDuration:self.animationDuration + delay:0 + usingSpringWithDamping:self.animationDampingRatio + initialSpringVelocity:self.animationVelocity + options:UIViewAnimationOptionCurveEaseInOut + animations:animations + completion:^(BOOL finished) { + completion(); + }]; + }; + } + animation(self.background, self.scrollView, completion); } /** @@ -720,10 +754,7 @@ - (void)buttonTapped:(TBActionButton *)sender NSUInteger index = [self.buttons indexOfObject:sender]; - [UIView animateWithDuration:self.animationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ - self.background.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; - self.scrollView.frame = CGRectMake(kContainerLeft, kScreenHeight, self.scrollView.frame.size.width, MIN(self.actionContainer.frame.size.height, kScreenHeight)); - } completion:^(BOOL finished) { + void(^completion)(void) = ^() { //这里之所以把各种 delegate 调用都放在动画完成后是有原因的:为了支持在回调方法中 show 另一个 actionsheet,系统的 UIActionSheet 的调用时机也是如此。 if ([self.delegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)]) { @@ -744,8 +775,11 @@ - (void)buttonTapped:(TBActionButton *)sender [self.delegate actionSheet:self didDismissWithButtonIndex:index]; } self.visible = NO; - }]; + }; + // 优先使用按钮动画,其次是关闭动画 + TBActionSheetAnimation animation = sender.animation ?: self.closeAnimation; + animation(self.background, self.scrollView, completion); } #pragma mark - handle close @@ -753,15 +787,17 @@ - (void)buttonTapped:(TBActionButton *)sender * 取消 ActionSheet 的方法 */ - (void)close +{ + [self closeWithAnimation:nil]; +} + +- (void)closeWithAnimation:(TBActionSheetAnimation)animation { if (![self isVisible]) { return; } - [UIView animateWithDuration:self.animationDuration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ - self.background.backgroundColor = [UIColor colorWithWhite:0 alpha:0]; - self.scrollView.frame = CGRectMake(kContainerLeft, kScreenHeight, self.scrollView.frame.size.width, MIN(self.actionContainer.frame.size.height, kScreenHeight)); - } completion:^(BOOL finished) { + void(^completion)(void) = ^() { [self cleanWindow]; if ([self.delegate respondsToSelector:@selector(actionSheetCancel:)]) { @@ -786,9 +822,14 @@ - (void)close [self.delegate actionSheet:self didDismissWithButtonIndex:self.cancelButtonIndex]; } } - + self.visible = NO; - }]; + }; + + // 关闭动画 + animation = animation ?: self.closeAnimation; + + animation(self.background, self.scrollView, completion); } - (void)cleanWindow diff --git a/Source/TBActionSheet/UIWindow+TBAdditions.m b/Source/TBActionSheet/UIWindow+TBAdditions.m index 5b85f8b..110d552 100644 --- a/Source/TBActionSheet/UIWindow+TBAdditions.m +++ b/Source/TBActionSheet/UIWindow+TBAdditions.m @@ -16,10 +16,8 @@ @implementation UIWindow (TBAdditions) - (UIViewController *)tb_viewControllerForStatusBarStyle { UIViewController *currentViewController = [self currentViewController]; - if (kiOS7Later) { - while ([currentViewController childViewControllerForStatusBarStyle]) { - currentViewController = [currentViewController childViewControllerForStatusBarStyle]; - } + while ([currentViewController childViewControllerForStatusBarStyle]) { + currentViewController = [currentViewController childViewControllerForStatusBarStyle]; } return currentViewController; } @@ -27,10 +25,8 @@ - (UIViewController *)tb_viewControllerForStatusBarStyle - (UIViewController *)tb_viewControllerForStatusBarHidden { UIViewController *currentViewController = [self currentViewController]; - if (kiOS7Later) { - while ([currentViewController childViewControllerForStatusBarHidden]) { - currentViewController = [currentViewController childViewControllerForStatusBarHidden]; - } + while ([currentViewController childViewControllerForStatusBarHidden]) { + currentViewController = [currentViewController childViewControllerForStatusBarHidden]; } return currentViewController; } diff --git a/Source/Utils/TBMacro.h b/Source/Utils/TBMacro.h index 180b489..e2485ff 100644 --- a/Source/Utils/TBMacro.h +++ b/Source/Utils/TBMacro.h @@ -26,11 +26,10 @@ _Pragma("clang diagnostic pop") #pragma mark - const values -#define kScreenWidth [UIScreen mainScreen].bounds.size.width -#define kScreenHeight [UIScreen mainScreen].bounds.size.height +#define kScreenWidth ([UIScreen mainScreen].bounds.size.width) +#define kScreenHeight ([UIScreen mainScreen].bounds.size.height) #define kContainerLeft ((kScreenWidth - self.sheetWidth)/2) -#define kiOS7Later SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0") #define kiOS8Later SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0") #define kiOS9Later SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0") #define kiOS10Later SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0") diff --git a/TBActionSheet.podspec b/TBActionSheet.podspec index 7b57def..41d817e 100644 --- a/TBActionSheet.podspec +++ b/TBActionSheet.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "TBActionSheet" -s.version = "1.6.5" +s.version = "1.7.0" s.summary = "A Custom&Magical ActionSheet." s.description = <<-DESC TBActionSheet is a small library that allows you to substitute Apple's uncustomizable UIActionSheet, with a beautiful and totally customizable actionsheet that you can use in your iOS app. The default style is iOS9/10, you can make your own style. Enjoy! @@ -13,7 +13,7 @@ s.author = { "YangXiaoyu" => "yulingtianxia@gmail.com" } s.social_media_url = 'https://twitter.com/yulingtianxia' s.source = { :git => "https://github.com/yulingtianxia/TBActionSheet.git", :tag => s.version.to_s } -s.platform = :ios, '6.0' +s.platform = :ios, '7.0' s.requires_arc = true s.source_files = "Source/**/*.{h,m}"