@@ -51,9 +51,13 @@ @interface SIAlertView ()
5151@property (nonatomic , strong ) UILabel *messageLabel;
5252@property (nonatomic , strong ) UIView *containerView;
5353@property (nonatomic , strong ) NSMutableArray *buttons;
54+ @property (nonatomic , strong ) UIActivityIndicatorView *activityIndicatorView;
55+ @property (nonatomic , strong ) UISegmentedControl *segmentedControl;
5456
5557@property (nonatomic , assign , getter = isLayoutDirty) BOOL layoutDirty;
5658
59+ @property (nonatomic , assign , getter = isShownInView) BOOL shownInView;
60+
5761+ (NSMutableArray *)sharedQueue ;
5862+ (SIAlertView *)currentAlertView ;
5963
@@ -247,6 +251,7 @@ + (void)initialize
247251 appearance.destructiveButtonColor = [UIColor whiteColor ];
248252 appearance.cornerRadius = 2 ;
249253 appearance.shadowRadius = 8 ;
254+ appearance.shouldShowBackground = (NSInteger )YES ;
250255}
251256
252257- (id )init
@@ -359,6 +364,12 @@ - (void)addButtonWithTitle:(NSString *)title type:(SIAlertViewButtonType)type ha
359364 [self .items addObject: item];
360365}
361366
367+ - (NSString *)selectedSegmentTitle
368+ {
369+ NSUInteger selectedIndex = self.segmentedControl .selectedSegmentIndex ;
370+ return [self .segmentedControl titleForSegmentAtIndex: selectedIndex];
371+ }
372+
362373- (void )show
363374{
364375 if (self.isVisible ) {
@@ -397,9 +408,11 @@ - (void)show
397408 [SIAlertView setAnimating: YES ];
398409 [SIAlertView setCurrentAlertView: self ];
399410
400- // transition background
411+ // transition background
412+ if (self.shouldShowBackground ) {
401413 [SIAlertView showBackground ];
402-
414+ }
415+
403416 SIAlertViewController *viewController = [[SIAlertViewController alloc ] initWithNibName: nil bundle: nil ];
404417 viewController.alertView = self;
405418
@@ -433,6 +446,79 @@ - (void)show
433446 }];
434447}
435448
449+ - (void )showInView : (UIView *)view
450+ {
451+ self.shownInView = YES ;
452+
453+ if (![[SIAlertView sharedQueue ] containsObject: self ]) {
454+ [[SIAlertView sharedQueue ] addObject: self ];
455+ }
456+
457+ if ([SIAlertView isAnimating ]) {
458+ return ; // wait for next turn
459+ }
460+
461+ if (self.isVisible ) {
462+ return ;
463+ }
464+
465+ if ([SIAlertView currentAlertView ].isVisible ) {
466+ SIAlertView *alert = [SIAlertView currentAlertView ];
467+ [alert dismissAnimated: YES cleanup: NO ];
468+ return ;
469+ }
470+
471+ if (self.willShowHandler ) {
472+ self.willShowHandler (self);
473+ }
474+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter ];
475+ [nc postNotificationName: SIAlertViewWillShowNotification
476+ object: self
477+ userInfo: nil ];
478+
479+ self.visible = YES ;
480+
481+ [SIAlertView setAnimating: YES ];
482+ [SIAlertView setCurrentAlertView: self ];
483+
484+ [self setup ];
485+
486+ self.frame = view.bounds ;
487+
488+ [self validateLayout ];
489+
490+ [view addSubview: self ];
491+
492+
493+ [self transitionInCompletion: ^{
494+ if (self.didShowHandler ) {
495+ self.didShowHandler (self);
496+ }
497+ [nc postNotificationName: SIAlertViewDidShowNotification
498+ object: self
499+ userInfo: nil ];
500+
501+ [SIAlertView setAnimating: NO ];
502+
503+ NSInteger index = [[SIAlertView sharedQueue ] indexOfObject: self ];
504+ if (index < [SIAlertView sharedQueue ].count - 1 ) {
505+ [self dismissAnimated: YES cleanup: NO ]; // dismiss to show next alert view
506+ }
507+ }];
508+ }
509+
510+ - (BOOL )pointInside : (CGPoint)point withEvent : (UIEvent *)event
511+ {
512+ if (self.shownInView )
513+ {
514+ return CGRectContainsPoint (self.containerView .frame , point);
515+ }
516+ else
517+ {
518+ return [super pointInside: point withEvent: event];
519+ }
520+ }
521+
436522- (void )dismissAnimated : (BOOL )animated
437523{
438524 [self dismissAnimated: animated cleanup: YES ];
@@ -454,7 +540,9 @@ - (void)dismissAnimated:(BOOL)animated cleanup:(BOOL)cleanup
454540
455541 void (^dismissComplete)(void ) = ^{
456542 self.visible = NO ;
457-
543+
544+ UIView *superview = self.superview ;
545+
458546 [self teardown ];
459547
460548 [SIAlertView setCurrentAlertView: nil ];
@@ -484,43 +572,55 @@ - (void)dismissAnimated:(BOOL)animated cleanup:(BOOL)cleanup
484572 }
485573
486574 if (nextAlertView) {
487- [nextAlertView show ];
575+ if (self.shownInView ) {
576+ [nextAlertView showInView: superview];
577+ } else {
578+ [nextAlertView show ];
579+ }
488580 } else {
489581 // show last alert view
490582 if ([SIAlertView sharedQueue ].count > 0 ) {
491583 SIAlertView *alert = [[SIAlertView sharedQueue ] lastObject ];
492- [alert show ];
584+ if (self.shownInView ) {
585+ [alert showInView: superview];
586+ } else {
587+ [alert show ];
588+ }
493589 }
494590 }
495591 };
496592
497593 if (animated && isVisible) {
498594 [SIAlertView setAnimating: YES ];
499595 [self transitionOutCompletion: dismissComplete];
500-
501- if ([SIAlertView sharedQueue ].count == 1 ) {
502- [SIAlertView hideBackgroundAnimated: YES ];
596+
597+ if (self.shouldShowBackground ) {
598+ if ([SIAlertView sharedQueue ].count == 1 ) {
599+ [SIAlertView hideBackgroundAnimated: YES ];
600+ }
503601 }
504-
602+
505603 } else {
506604 dismissComplete ();
507605
508606 if ([SIAlertView sharedQueue ].count == 0 ) {
509607 [SIAlertView hideBackgroundAnimated: YES ];
510608 }
511609 }
512-
513- UIWindow *window = self.oldKeyWindow ;
610+
611+ if (!self.shownInView ) {
612+ UIWindow *window = self.oldKeyWindow ;
514613#ifdef __IPHONE_7_0
515- if ([window respondsToSelector: @selector (setTintAdjustmentMode: )]) {
516- window.tintAdjustmentMode = self.oldTintAdjustmentMode ;
517- }
614+ if ([window respondsToSelector: @selector (setTintAdjustmentMode: )]) {
615+ window.tintAdjustmentMode = self.oldTintAdjustmentMode ;
616+ }
518617#endif
519- if (!window) {
520- window = [UIApplication sharedApplication ].windows [0 ];
618+ if (!window) {
619+ window = [UIApplication sharedApplication ].windows [0 ];
620+ }
621+ [window makeKeyWindow ];
622+ window.hidden = NO ;
521623 }
522- [window makeKeyWindow ];
523- window.hidden = NO ;
524624}
525625
526626#pragma mark - Transitions
@@ -734,18 +834,55 @@ - (void)validateLayout
734834 if (self.titleLabel ) {
735835 self.titleLabel .text = self.title ;
736836 CGFloat height = [self heightForTitleLabel ];
737- self.titleLabel .frame = CGRectMake (CONTENT_PADDING_LEFT, y, self.containerView .bounds .size .width - CONTENT_PADDING_LEFT * 2 , height);
837+ CGRect frame = CGRectMake (
838+ CONTENT_PADDING_LEFT,
839+ y,
840+ self.containerView .bounds .size .width - CONTENT_PADDING_LEFT * 2 ,
841+ height
842+ );
843+
844+ if (self.waiting ) {
845+ frame.size .width -= CONTENT_PADDING_LEFT + self.activityIndicatorView .frame .size .width ;
846+ }
847+
848+ self.titleLabel .frame = frame;
738849 y += height;
739- }
850+ }
851+ if (self.activityIndicatorView ) {
852+ CGRect frame = self.activityIndicatorView .frame ;
853+ frame.origin .x = self.containerView .bounds .size .width - CONTENT_PADDING_LEFT - frame.size .width ;
854+ frame.origin .y = (self.containerView .bounds .size .height - frame.size .height ) / 2 .f ;
855+ self.activityIndicatorView .frame = frame;
856+ }
740857 if (self.messageLabel ) {
741858 if (y > CONTENT_PADDING_TOP) {
742859 y += GAP;
743860 }
744861 self.messageLabel .text = self.message ;
745862 CGFloat height = [self heightForMessageLabel ];
746- self.messageLabel .frame = CGRectMake (CONTENT_PADDING_LEFT, y, self.containerView .bounds .size .width - CONTENT_PADDING_LEFT * 2 , height);
863+ CGRect frame =
864+ CGRectMake (
865+ CONTENT_PADDING_LEFT,
866+ y,
867+ self.containerView .bounds .size .width - CONTENT_PADDING_LEFT * 2 ,
868+ height
869+ );
870+ if (self.waiting ) {
871+ frame.size .width -= CONTENT_PADDING_LEFT + self.activityIndicatorView .frame .size .width ;
872+ }
873+ self.messageLabel .frame = frame;
747874 y += height;
748875 }
876+ if (self.segmentedControl ) {
877+ if (y > CONTENT_PADDING_TOP) {
878+ y += GAP;
879+ }
880+ CGRect frame = self.segmentedControl .frame ;
881+ frame.origin .x = (self.containerView .bounds .size .width - frame.size .width ) / 2 .f ;
882+ frame.origin .y = y;
883+ self.segmentedControl .frame = frame;
884+ y += frame.size .height ;
885+ }
749886 if (self.items .count > 0 ) {
750887 if (y > CONTENT_PADDING_TOP) {
751888 y += GAP;
@@ -785,6 +922,12 @@ - (CGFloat)preferredHeight
785922 }
786923 height += [self heightForMessageLabel ];
787924 }
925+ if (self.segmentedControlTitles ) {
926+ if (height > CONTENT_PADDING_TOP) {
927+ height += GAP;
928+ }
929+ height += self.segmentedControl .frame .size .height ;
930+ }
788931 if (self.items .count > 0 ) {
789932 if (height > CONTENT_PADDING_TOP) {
790933 height += GAP;
@@ -874,22 +1017,30 @@ - (CGFloat)heightForMessageLabel
8741017
8751018- (void )setup
8761019{
877- [self setupContainerView ];
878- [self updateTitleLabel ];
879- [self updateMessageLabel ];
880- [self setupButtons ];
881- [self invalidateLayout ];
1020+ [self setupContainerView ];
1021+ [self updateActivityIndicator ];
1022+ [self updateSegmentedControl ];
1023+ [self updateTitleLabel ];
1024+ [self updateMessageLabel ];
1025+ [self setupButtons ];
1026+ [self invalidateLayout ];
8821027}
8831028
8841029- (void )teardown
8851030{
8861031 [self .containerView removeFromSuperview ];
8871032 self.containerView = nil ;
1033+ self.activityIndicatorView = nil ;
1034+ self.segmentedControl = nil ;
8881035 self.titleLabel = nil ;
8891036 self.messageLabel = nil ;
8901037 [self .buttons removeAllObjects ];
891- [self .alertWindow removeFromSuperview ];
892- self.alertWindow = nil ;
1038+ if (self.shownInView ) {
1039+ [self removeFromSuperview ];
1040+ } else {
1041+ [self .alertWindow removeFromSuperview ];
1042+ self.alertWindow = nil ;
1043+ }
8931044 self.layoutDirty = NO ;
8941045}
8951046
@@ -904,6 +1055,48 @@ - (void)setupContainerView
9041055 [self addSubview: self .containerView];
9051056}
9061057
1058+ - (void )updateActivityIndicator
1059+ {
1060+ if (self.waiting ) {
1061+ if (!self.activityIndicatorView ) {
1062+ self.activityIndicatorView =
1063+ [[UIActivityIndicatorView alloc ] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge];
1064+ [self .activityIndicatorView startAnimating ];
1065+ [self .containerView addSubview: self .activityIndicatorView];
1066+ }
1067+ } else {
1068+ [self .activityIndicatorView removeFromSuperview ];
1069+ self.activityIndicatorView = nil ;
1070+ }
1071+ [self invalidateLayout ];
1072+ }
1073+
1074+ - (void )updateSegmentedControl
1075+ {
1076+ if (self.segmentedControlTitles .count > 0 ) {
1077+ if (!self.segmentedControl ) {
1078+ self.segmentedControl =
1079+ [[UISegmentedControl alloc ] initWithItems: self .segmentedControlTitles];
1080+ [self .segmentedControl setSelectedSegmentIndex: self .initiallySegmentedControlSelectedIndex];
1081+
1082+ // Make sure the segments have some minimum width
1083+ NSUInteger index = 0 ;
1084+ for (NSString *title in self.segmentedControlTitles ) {
1085+ if (title.length < 2 ) {
1086+ [self .segmentedControl setWidth: 30 .f forSegmentAtIndex: index];
1087+ }
1088+ index++;
1089+ }
1090+
1091+ [self .containerView addSubview: self .segmentedControl];
1092+ }
1093+ } else {
1094+ [self .segmentedControl removeFromSuperview ];
1095+ self.segmentedControl = nil ;
1096+ }
1097+ [self invalidateLayout ];
1098+ }
1099+
9071100- (void )updateTitleLabel
9081101{
9091102 if (self.title ) {
0 commit comments