SWActionSheet.m 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //
  2. // Created by Petr Korolev on 11/08/14.
  3. //
  4. #import "SWActionSheet.h"
  5. static const float delay = 0.f;
  6. static const float duration = .25f;
  7. static const enum UIViewAnimationOptions options = UIViewAnimationOptionCurveEaseIn;
  8. @interface SWActionSheetVC : UIViewController
  9. @property (nonatomic, retain) SWActionSheet *actionSheet;
  10. @end
  11. @interface SWActionSheet ()
  12. {
  13. UIWindow *SWActionSheetWindow;
  14. }
  15. @property (nonatomic, assign) BOOL presented;
  16. @property (nonatomic) UIWindowLevel windowLevel;
  17. - (void)configureFrameForBounds:(CGRect)bounds;
  18. - (void)showInContainerViewAnimated:(BOOL)animated;
  19. @end
  20. @implementation SWActionSheet
  21. {
  22. UIView *view;
  23. UIView *_bgView;
  24. }
  25. - (void)dismissWithClickedButtonIndex:(int)i animated:(BOOL)animated
  26. {
  27. CGPoint fadeOutToPoint = CGPointMake(view.center.x,
  28. self.center.y + CGRectGetHeight(view.frame));
  29. // Window of app
  30. //UIWindow *appWindow = [UIApplication sharedApplication].windows.firstObject;
  31. // Actions
  32. void (^actions)(void) = ^{
  33. self.center = fadeOutToPoint;
  34. self.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.0f];
  35. };
  36. void (^completion)(BOOL) = ^(BOOL finished) {
  37. // if (![appWindow isKeyWindow])
  38. // [appWindow makeKeyAndVisible];
  39. [self destroyWindow];
  40. [self removeFromSuperview];
  41. };
  42. // Do actions animated or not
  43. if (animated) {
  44. [UIView animateWithDuration:duration delay:delay options:options animations:actions completion:completion];
  45. } else {
  46. actions();
  47. completion(YES);
  48. }
  49. self.presented = NO;
  50. }
  51. - (void)destroyWindow
  52. {
  53. if (SWActionSheetWindow)
  54. {
  55. [self actionSheetContainer].actionSheet = nil;
  56. SWActionSheetWindow.hidden = YES;
  57. if ([SWActionSheetWindow isKeyWindow])
  58. [SWActionSheetWindow resignFirstResponder];
  59. SWActionSheetWindow.rootViewController = nil;
  60. SWActionSheetWindow = nil;
  61. }
  62. }
  63. - (UIWindow *)window
  64. {
  65. if ( SWActionSheetWindow )
  66. {
  67. return SWActionSheetWindow;
  68. }
  69. else
  70. {
  71. return SWActionSheetWindow = ({
  72. UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  73. window.windowLevel = self.windowLevel;
  74. window.backgroundColor = [UIColor clearColor];
  75. window.rootViewController = [SWActionSheetVC new];
  76. window;
  77. });
  78. }
  79. }
  80. - (SWActionSheetVC *)actionSheetContainer
  81. {
  82. return (SWActionSheetVC *) [self window].rootViewController;
  83. }
  84. - (instancetype)initWithView:(UIView *)aView windowLevel:(UIWindowLevel)windowLevel
  85. {
  86. if ((self = [super init]))
  87. {
  88. view = aView;
  89. _windowLevel = windowLevel;
  90. self.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.0f];
  91. _bgView = [UIView new];
  92. _bgView.backgroundColor = [UIColor colorWithRed:247.f/255.f green:247.f/255.f blue:247.f/255.f alpha:1.0f];
  93. [self addSubview:_bgView];
  94. [self addSubview:view];
  95. }
  96. return self;
  97. }
  98. - (void)configureFrameForBounds:(CGRect)bounds
  99. {
  100. self.frame = CGRectMake(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height + view.bounds.size.height);
  101. view.frame = CGRectMake(view.bounds.origin.x, bounds.size.height, view.bounds.size.width, view.bounds.size.height);
  102. view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
  103. _bgView.frame = view.frame;
  104. _bgView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  105. }
  106. - (void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated
  107. {
  108. [self showInContainerView];
  109. }
  110. - (void)showInContainerView
  111. {
  112. // Make sheet window visible and active
  113. UIWindow *sheetWindow = [self window];
  114. if (![sheetWindow isKeyWindow])
  115. [sheetWindow makeKeyAndVisible];
  116. sheetWindow.hidden = NO;
  117. // Put our ActionSheet in Container (it will be presented as soon as possible)
  118. self.actionSheetContainer.actionSheet = self;
  119. }
  120. - (void)showInContainerViewAnimated:(BOOL)animated
  121. {
  122. CGPoint toPoint;
  123. CGFloat y = self.center.y - CGRectGetHeight(view.frame);
  124. toPoint = CGPointMake(self.center.x, y);
  125. // Present actions
  126. void (^animations)(void) = ^{
  127. self.center = toPoint;
  128. self.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.5f];
  129. };
  130. // Present sheet
  131. if (animated)
  132. [UIView animateWithDuration:duration delay:delay options:options animations:animations completion:nil];
  133. else
  134. animations();
  135. self.presented = YES;
  136. }
  137. @end
  138. #pragma mark - SWActionSheet Container
  139. @implementation SWActionSheetVC
  140. - (UIStatusBarStyle)preferredStatusBarStyle {
  141. return [UIApplication sharedApplication].statusBarStyle;
  142. }
  143. - (void)setActionSheet:(SWActionSheet *)actionSheet
  144. {
  145. // Prevent processing one action sheet twice
  146. if (_actionSheet == actionSheet)
  147. return;
  148. // Dissmiss previous action sheet if it presented
  149. if (_actionSheet.presented)
  150. [_actionSheet dismissWithClickedButtonIndex:0 animated:YES];
  151. // Remember new action sheet
  152. _actionSheet = actionSheet;
  153. // Present new action sheet
  154. [self presentActionSheetAnimated:YES];
  155. }
  156. - (void)viewWillAppear:(BOOL)animated
  157. {
  158. [super viewWillAppear:animated];
  159. [self presentActionSheetAnimated:YES];
  160. }
  161. - (void)presentActionSheetAnimated:(BOOL)animated
  162. {
  163. // New action sheet will be presented only when view controller will be loaded
  164. if (_actionSheet && [self isViewLoaded] && !_actionSheet.presented)
  165. {
  166. [_actionSheet configureFrameForBounds:self.view.bounds];
  167. _actionSheet.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  168. [self.view addSubview:_actionSheet];
  169. [_actionSheet showInContainerViewAnimated:animated];
  170. }
  171. }
  172. - (BOOL)prefersStatusBarHidden {
  173. return [UIApplication sharedApplication].statusBarHidden;
  174. }
  175. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  176. {
  177. return NO;
  178. }
  179. // iOS6 support
  180. // ---
  181. - (BOOL)shouldAutorotate
  182. {
  183. return YES;
  184. }
  185. @end