BSAlertView.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. //
  2. // BSAlertView.m
  3. // Unionpay
  4. //
  5. // Created by Qing Xiubin on 13-8-7.
  6. // Copyright (c) 2013年 成都中信联通科技有限公司. All rights reserved.
  7. //
  8. #if !__has_feature(objc_arc)
  9. #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
  10. #endif
  11. #define ALERT_TIME_DURATION 0.3f
  12. #define ALERT_ALPHA_HIDE 0.0f
  13. #define ALERT_ALPHA_SHOW 1.0f
  14. #define ALERT_COLOR_HIDE [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f]
  15. #define ALERT_COLOR_SHOW [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.6f]
  16. #import "BSAlertView.h"
  17. //#import "IQKeyboardManager.h"
  18. #import "UIView+XTExtension.h"
  19. @interface AlertController : UIViewController
  20. @property (nonatomic, assign) UIStatusBarStyle statusBarStyle;
  21. @end
  22. @implementation AlertController
  23. - (UIStatusBarStyle)preferredStatusBarStyle{
  24. return _statusBarStyle;
  25. }
  26. - (BOOL)prefersStatusBarHidden{
  27. return NO;
  28. }
  29. - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation{
  30. return UIStatusBarAnimationFade;
  31. }
  32. -(BOOL)shouldAutorotate
  33. {
  34. return YES;
  35. }
  36. -(UIInterfaceOrientationMask)supportedInterfaceOrientations
  37. {
  38. return UIInterfaceOrientationMaskPortrait;
  39. }
  40. @end
  41. @interface BSAlertView ()
  42. @property (assign, nonatomic) BOOL isShow;
  43. @property (strong, nonatomic) UIWindow *alertWindow;
  44. @property (strong, nonatomic) UIWindow *previousWindow;
  45. @end
  46. @implementation BSAlertView
  47. - (instancetype)init{
  48. return [super initWithFrame:CGRectZero];
  49. }
  50. - (instancetype)initWithFrame:(CGRect)frame{
  51. self = [super initWithFrame:frame];
  52. if (self)
  53. {
  54. self.allowAbserveKeyboard = YES;
  55. [self awakeFromNib];
  56. }
  57. return self;
  58. }
  59. - (void)awakeFromNib{
  60. [super awakeFromNib];
  61. self.backgroundColor = [UIColor clearColor];
  62. self.autoresizingMask =
  63. UIViewAutoresizingFlexibleTopMargin|
  64. UIViewAutoresizingFlexibleBottomMargin|
  65. UIViewAutoresizingFlexibleLeftMargin|
  66. UIViewAutoresizingFlexibleRightMargin;
  67. }
  68. /**********************************************************************/
  69. #pragma mark - Public Methods
  70. /**********************************************************************/
  71. - (void)show{
  72. return [self showWithAnimation:kAlertAnimationBottom];
  73. }
  74. - (void)bgViewTapAction:(UITapGestureRecognizer *)sender{
  75. [self dismiss];
  76. }
  77. - (void)showWithAnimation:(AlertAnimation)animation{
  78. if (_isShow == YES) {
  79. return;
  80. }
  81. _isShow = YES;
  82. if (self.allowAbserveKeyboard)
  83. {
  84. //监听键盘
  85. // [self observeKeyboard];
  86. }
  87. //设置Window
  88. [self setPreviousWindow:[[UIApplication sharedApplication] keyWindow]];
  89. _alertWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  90. [_alertWindow setWindowLevel:UIWindowLevelAlert];
  91. [_alertWindow setBackgroundColor:ALERT_COLOR_HIDE];
  92. AlertController *controller = [[AlertController alloc] init];
  93. [controller setStatusBarStyle:_statusBarStyle];
  94. [_alertWindow setRootViewController:controller];
  95. [_alertWindow.rootViewController.view addSubview:self];
  96. [_alertWindow makeKeyAndVisible];
  97. if (_gesture) {
  98. UIButton *bgButton = [UIButton buttonWithType:UIButtonTypeCustom];
  99. [bgButton setFrame:controller.view.bounds];
  100. [bgButton setBackgroundColor:[UIColor clearColor]];
  101. [bgButton addTarget:self action:@selector(bgViewTapAction:) forControlEvents:UIControlEventTouchUpInside];
  102. [controller.view insertSubview:bgButton belowSubview:self];
  103. }
  104. //弹窗动画
  105. switch (animation) {
  106. case kAlertAnimationTop:
  107. case kAlertAnimationBottom:
  108. case kAlertAnimationLeft:
  109. case kAlertAnimationRight:{
  110. [self setAlpha:ALERT_ALPHA_SHOW];
  111. [self setCenter:[self centerWithAnimation:animation]];
  112. [UIView animateWithDuration:ALERT_TIME_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  113. [self setCenter:[self centerWithAnimation:kAlertAnimationNone]];
  114. if (self.bgColor) {
  115. [self.alertWindow setBackgroundColor:self.bgColor];
  116. }else{
  117. [self.alertWindow setBackgroundColor:ALERT_COLOR_SHOW];
  118. }
  119. } completion:nil];
  120. }break;
  121. case kAlertAnimationFade:{
  122. [self setAlpha:ALERT_ALPHA_HIDE];
  123. [self setCenter:[self centerWithAnimation:animation]];
  124. [UIView animateWithDuration:ALERT_TIME_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  125. [self setAlpha:ALERT_ALPHA_SHOW];
  126. if (self.bgColor) {
  127. [self.alertWindow setBackgroundColor:self.bgColor];
  128. }else{
  129. [self.alertWindow setBackgroundColor:ALERT_COLOR_SHOW];
  130. }
  131. } completion:nil];
  132. }break;
  133. case kAlertAnimationPop:{
  134. [self setAlpha:ALERT_ALPHA_HIDE];
  135. [self setCenter:[self centerWithAnimation:animation]];
  136. [UIView animateWithDuration:ALERT_TIME_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  137. [self setAlpha:ALERT_ALPHA_SHOW];
  138. if (self.bgColor) {
  139. [self.alertWindow setBackgroundColor:self.bgColor];
  140. }else{
  141. [self.alertWindow setBackgroundColor:ALERT_COLOR_SHOW];
  142. }
  143. } completion:nil];
  144. CAKeyframeAnimation *scaleAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
  145. scaleAnimation.removedOnCompletion = YES;
  146. scaleAnimation.duration = ALERT_TIME_DURATION;
  147. scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
  148. scaleAnimation.values = @[@0.01f,@1.1f,@0.9f,@1.0f];
  149. [self.layer addAnimation:scaleAnimation forKey:nil];
  150. }break;
  151. case kAlertAnimationNone:
  152. default:{
  153. [self setAlpha:ALERT_ALPHA_SHOW];
  154. [self setCenter:[self centerWithAnimation:kAlertAnimationNone]];
  155. if (self.bgColor) {
  156. [self.alertWindow setBackgroundColor:self.bgColor];
  157. }else{
  158. [self.alertWindow setBackgroundColor:ALERT_COLOR_SHOW];
  159. }
  160. }break;
  161. }
  162. }
  163. - (void)dismiss{
  164. return [self dismissWithAnimation:kAlertAnimationFade];
  165. }
  166. - (void)dismissWithAnimation:(AlertAnimation)animation{
  167. if (_isShow == NO) {
  168. return;
  169. }
  170. _isShow = NO;
  171. //隐藏键盘
  172. // [self unObserveKeyboard];
  173. [self endEditing:YES];
  174. //恢复Window
  175. [self.previousWindow makeKeyWindow];
  176. //弹窗动画
  177. switch (animation) {
  178. case kAlertAnimationTop:
  179. case kAlertAnimationBottom:
  180. case kAlertAnimationLeft:
  181. case kAlertAnimationRight:{
  182. [UIView animateWithDuration:ALERT_TIME_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  183. [self setCenter:[self centerWithAnimation:animation]];
  184. [self.alertWindow setBackgroundColor:ALERT_COLOR_HIDE];
  185. } completion:^(BOOL finished) {
  186. [self removeFromSuperview];
  187. }];
  188. }break;
  189. case kAlertAnimationFade:
  190. case kAlertAnimationPop:{
  191. [UIView animateWithDuration:ALERT_TIME_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  192. [self setAlpha:ALERT_ALPHA_HIDE];
  193. [self.alertWindow setBackgroundColor:ALERT_COLOR_HIDE];
  194. } completion:^(BOOL finished) {
  195. [self removeFromSuperview];
  196. }];
  197. }break;
  198. case kAlertAnimationNone:
  199. default:{
  200. [self setAlpha:ALERT_ALPHA_HIDE];
  201. [self.alertWindow setBackgroundColor:ALERT_COLOR_HIDE];
  202. [self removeFromSuperview];
  203. }break;
  204. }
  205. }
  206. /**********************************************************************/
  207. #pragma mark - Public Methods
  208. /**********************************************************************/
  209. - (BOOL)willShowKeyboard{
  210. if ([self firstResponder] == nil) {
  211. return NO;
  212. }
  213. return YES;
  214. }
  215. - (CGFloat)marginToBottom{
  216. return 255;
  217. }
  218. - (CGPoint)centerWithAnimation:(AlertAnimation)animation{
  219. CGRect bounds = self.window.rootViewController.view.bounds;
  220. CGPoint center = CGPointZero;
  221. switch (animation) {
  222. case kAlertAnimationTop:{
  223. center.x = bounds.size.width/2;
  224. center.y = 0-bounds.size.height/2;
  225. }break;
  226. case kAlertAnimationBottom:{
  227. center.x = bounds.size.width/2;
  228. center.y = bounds.size.height+self.bounds.size.height/2;
  229. }break;
  230. case kAlertAnimationLeft:{
  231. center.x = 0-bounds.size.width/2;
  232. if ([self willShowKeyboard]) {
  233. center.y = bounds.size.height-(self.bounds.size.height/2+[self marginToBottom]);
  234. } else {
  235. center.y = bounds.size.height/2;
  236. }
  237. }break;
  238. case kAlertAnimationRight:{
  239. center.x = bounds.size.width+bounds.size.width/2;
  240. if ([self willShowKeyboard]) {
  241. center.y = bounds.size.height-(self.bounds.size.height/2+[self marginToBottom]);
  242. } else {
  243. center.y = bounds.size.height/2;
  244. }
  245. }break;
  246. case kAlertAnimationFade:
  247. case kAlertAnimationPop:
  248. case kAlertAnimationNone:
  249. default:{
  250. center.x = bounds.size.width/2;
  251. if ([self willShowKeyboard]) {
  252. center.y = bounds.size.height-(self.bounds.size.height/2+[self marginToBottom]);
  253. } else {
  254. center.y = bounds.size.height/2;
  255. }
  256. }break;
  257. }
  258. return center;
  259. }
  260. /**********************************************************************/
  261. #pragma mark - UIKeyboard
  262. /**********************************************************************/
  263. - (void)keyboardWillShow:(CGRect)frame duration:(NSTimeInterval)duration curve:(NSUInteger)curve{
  264. if (_isShow) {
  265. CGRect bounds = self.window.rootViewController.view.bounds;
  266. CGPoint center = self.center;
  267. center.y = bounds.size.height-(self.bounds.size.height/2+[self marginToBottom]);
  268. [UIView animateWithDuration:duration delay:0 options:curve animations:^{
  269. [self setCenter:center];
  270. } completion:nil];
  271. }
  272. }
  273. - (void)keyboardWillHide:(CGRect)frame duration:(NSTimeInterval)duration curve:(NSUInteger)curve{
  274. if (_isShow) {
  275. CGRect bounds = self.window.rootViewController.view.bounds;
  276. CGPoint center = self.center;
  277. center.y = bounds.size.height/2;
  278. [UIView animateWithDuration:duration delay:0 options:curve animations:^{
  279. [self setCenter:center];
  280. } completion:nil];
  281. }
  282. }
  283. @end