JSAlertView.m 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. //
  2. // JSAlertView.m
  3. // JSAlertView
  4. //
  5. // Created by Jitendra Singh on 10/12/16.
  6. // Copyright © 2016 Jitendra Singh. All rights reserved.
  7. //
  8. #import "JSAlertView.h"
  9. @interface JSAlertView ()
  10. @property (nonatomic, copy) void(^completionBlock)(NSInteger buttonIndex, NSString *buttonTitle);
  11. @property (nonatomic, copy) void(^confirmationBlock)(BOOL accepted);
  12. @property (nonatomic, strong) UIWindow *thisAlertWindow;
  13. @property (nonatomic, strong) NSMutableArray *allAlertWindows;
  14. @end
  15. @implementation JSAlertView
  16. + (instancetype)sharedInstance {
  17. static dispatch_once_t predicate;
  18. static JSAlertView *instance = nil;
  19. dispatch_once(&predicate, ^{
  20. instance = [[self alloc] init];
  21. [instance initalization];
  22. });
  23. return instance;
  24. }
  25. - (void)initalization
  26. {
  27. // do write all initalization code here
  28. self.allAlertWindows = [NSMutableArray arrayWithCapacity:0];
  29. }
  30. + (instancetype)alert:(NSString*)message
  31. {
  32. return [self alert:message withTitle:nil buttons:@[@"Ok"] withCompletionHandler:nil];
  33. }
  34. + (instancetype)confirm:(NSString*)message withCompletionHandler:(void(^)(BOOL accepted))completionHandler
  35. {
  36. return [self confirm:message withTitle:nil withCompletionHandler:completionHandler];
  37. }
  38. + (instancetype)confirm:(NSString*)message withTitle:(NSString*)title withCompletionHandler:(void(^)(BOOL accepted))completionHandler
  39. {
  40. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
  41. JSAlertView *alert = [JSAlertView alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
  42. UIAlertAction* noButton = [UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  43. [alert dismissViewControllerAnimated:YES completion:nil];
  44. if (completionHandler) {
  45. completionHandler(NO);
  46. }
  47. }];
  48. [alert addAction:noButton];
  49. UIAlertAction* yesButton = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  50. [alert dismissViewControllerAnimated:YES completion:nil];
  51. if (completionHandler) {
  52. completionHandler(YES);
  53. }
  54. }];
  55. [alert addAction:yesButton];
  56. [alert show];
  57. return alert;
  58. #else
  59. JSAlertView *alert = [[JSAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
  60. __weak __typeof__(alert) alert_weak_ = (alert);
  61. [alert setDelgate:alert_weak_];
  62. [alert addButtonWithTitle:@"No"];
  63. [alert addButtonWithTitle:@"Yes"];
  64. alert.confirmationBlock = completionHandler;
  65. [alert show];
  66. return alert;
  67. #endif
  68. }
  69. + (instancetype)alert:(NSString*)message withTitle:(NSString*)title buttons:(NSArray*)buttonTitles withCompletionHandler:(void(^)(NSInteger buttonIndex, NSString *buttonTitle))completionHandler
  70. {
  71. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
  72. JSAlertView *alert = [JSAlertView alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
  73. for (NSString *btnTitle in buttonTitles) {
  74. UIAlertAction* button = [UIAlertAction actionWithTitle:btnTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  75. [alert dismissViewControllerAnimated:YES completion:nil];
  76. if (completionHandler) {
  77. completionHandler([buttonTitles indexOfObject:btnTitle], btnTitle);
  78. }
  79. }];
  80. [alert addAction:button];
  81. }
  82. [alert show];
  83. return alert;
  84. #else
  85. JSAlertView *alert = [[JSAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
  86. __weak __typeof__(alert) alert_weak_ = (alert);
  87. [alert setDelgate:alert_weak_];
  88. __block NSInteger index = 0;
  89. for (NSString *btnTitle in buttonTitles) {
  90. [alert addButtonWithTitle:btnTitle];
  91. }
  92. alert.completionBlock = completionHandler;
  93. [alert show];
  94. return alert;
  95. #endif
  96. }
  97. - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
  98. {
  99. if (self.completionBlock) {
  100. self.completionBlock(buttonIndex, [alertView buttonTitleAtIndex:buttonIndex]);
  101. }
  102. else if (self.confirmationBlock) {
  103. self.confirmationBlock(!(buttonIndex == 0));
  104. }
  105. }
  106. + (BOOL)isOpenAlertWindows
  107. {
  108. return [[JSAlertView sharedInstance].allAlertWindows count];
  109. }
  110. /***********************************************************************
  111. *
  112. * Following methods will be used for iOS 8 or later for UIAlertController
  113. *
  114. ***********************************************************************/
  115. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
  116. - (void)show {
  117. [self show:YES];
  118. }
  119. - (void)show:(BOOL)animated {
  120. //create a new window for the alert
  121. self.thisAlertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  122. self.thisAlertWindow.rootViewController = [[UIViewController alloc] init];
  123. // set this window on top in stack
  124. UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;
  125. self.thisAlertWindow.windowLevel = topWindow.windowLevel + 1;
  126. // make it visible and show alert
  127. [self.thisAlertWindow makeKeyAndVisible];
  128. [self.thisAlertWindow.rootViewController presentViewController:self animated:animated completion:nil];
  129. // set alpha 0.0 for last alert to make it transparent, this will give feel of single alert displayed on screen
  130. [[JSAlertView sharedInstance].allAlertWindows.lastObject setAlpha:0.0];
  131. [[JSAlertView sharedInstance].allAlertWindows addObject:self.thisAlertWindow];
  132. }
  133. - (void)viewWillDisappear:(BOOL)animated {
  134. [super viewWillDisappear:animated];
  135. // remove this window from stack
  136. [[JSAlertView sharedInstance].allAlertWindows removeObject:self.thisAlertWindow];
  137. // set alpha 1.0 for last alert to make it appear
  138. [UIView animateWithDuration:0.3 animations:^{
  139. [[JSAlertView sharedInstance].allAlertWindows.lastObject setAlpha:1.0];
  140. }];
  141. }
  142. - (void)viewDidDisappear:(BOOL)animated {
  143. [super viewDidDisappear:animated];
  144. // once the alert is disappeared set window property to nil, else it will create retain cycle
  145. self.thisAlertWindow.hidden = YES;
  146. self.thisAlertWindow = nil;
  147. }
  148. #endif
  149. @end