JSAlertView.m 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. /***********************************************************************
  107. *
  108. * Following methods will be used for iOS 8 or later for UIAlertController
  109. *
  110. ***********************************************************************/
  111. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
  112. - (void)show {
  113. [self show:YES];
  114. }
  115. - (void)show:(BOOL)animated {
  116. //create a new window for the alert
  117. self.thisAlertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  118. self.thisAlertWindow.rootViewController = [[UIViewController alloc] init];
  119. // set this window on top in stack
  120. UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;
  121. self.thisAlertWindow.windowLevel = topWindow.windowLevel + 1;
  122. // make it visible and show alert
  123. [self.thisAlertWindow makeKeyAndVisible];
  124. [self.thisAlertWindow.rootViewController presentViewController:self animated:animated completion:nil];
  125. // set alpha 0.0 for last alert to make it transparent, this will give feel of single alert displayed on screen
  126. [[JSAlertView sharedInstance].allAlertWindows.lastObject setAlpha:0.0];
  127. [[JSAlertView sharedInstance].allAlertWindows addObject:self.thisAlertWindow];
  128. }
  129. - (void)viewWillDisappear:(BOOL)animated {
  130. [super viewWillDisappear:animated];
  131. // remove this window from stack
  132. [[JSAlertView sharedInstance].allAlertWindows removeObject:self.thisAlertWindow];
  133. // set alpha 1.0 for last alert to make it appear
  134. [UIView animateWithDuration:0.3 animations:^{
  135. [[JSAlertView sharedInstance].allAlertWindows.lastObject setAlpha:1.0];
  136. }];
  137. }
  138. - (void)viewDidDisappear:(BOOL)animated {
  139. [super viewDidDisappear:animated];
  140. // once the alert is disappeared set window property to nil, else it will create retain cycle
  141. self.thisAlertWindow.hidden = YES;
  142. self.thisAlertWindow = nil;
  143. }
  144. #endif
  145. @end