Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions SIAlertView/SIAlertView.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,21 @@ typedef NS_ENUM(NSInteger, SIAlertViewTransitionStyle) {
SIAlertViewTransitionStyleDropDown
};

typedef NS_ENUM(NSInteger, SIAlertViewStyle) {
SIAlertViewStyleDefault = 0,
SIAlertViewStylePlainTextInput
};

@class SIAlertView;
typedef void(^SIAlertViewHandler)(SIAlertView *alertView);

@interface SIAlertView : UIView

@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *message;
@property (nonatomic, copy, readonly) NSString *inputText;

@property (nonatomic, assign) SIAlertViewStyle alertViewStyle; // default is SIAlertViewStyleDefault
@property (nonatomic, assign) SIAlertViewTransitionStyle transitionStyle; // default is SIAlertViewTransitionStyleSlideFromBottom
@property (nonatomic, assign) SIAlertViewBackgroundStyle backgroundStyle; // default is SIAlertViewButtonTypeGradient

Expand Down
109 changes: 108 additions & 1 deletion SIAlertView/SIAlertView.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define CONTENT_PADDING_TOP 12
#define CONTENT_PADDING_BOTTOM 10
#define BUTTON_HEIGHT 44
#define TEXTFIELD_HEIGHT 28
#define CONTAINER_WIDTH 300

const UIWindowLevel UIWindowLevelSIAlert = 1999.0; // don't overlap system's alert
Expand All @@ -44,9 +45,12 @@ @interface SIAlertView ()

@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *messageLabel;
@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, strong) NSMutableArray *buttons;

@property (nonatomic, assign) CGFloat keyboardOffset;

@property (nonatomic, assign, getter = isLayoutDirty) BOOL layoutDirty;

+ (NSMutableArray *)sharedQueue;
Expand Down Expand Up @@ -167,6 +171,9 @@ - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrie

#pragma mark - SIAlert

@interface SIAlertView() <UITextFieldDelegate>
@end

@implementation SIAlertView

+ (void)initialize
Expand Down Expand Up @@ -262,6 +269,12 @@ + (void)hideBackgroundAnimated:(BOOL)animated
}];
}

#pragma mark - Getters

- (NSString *)inputText {
return self.textField ? self.textField.text : @"";
}

#pragma mark - Setters

- (void)setTitle:(NSString *)title
Expand Down Expand Up @@ -346,6 +359,8 @@ - (void)show
NSInteger index = [[SIAlertView sharedQueue] indexOfObject:self];
if (index < [SIAlertView sharedQueue].count - 1) {
[self dismissAnimated:YES cleanup:NO]; // dismiss to show next alert view
} else if(self.textField) {
[self.textField becomeFirstResponder];
}
}];
}
Expand All @@ -363,6 +378,13 @@ - (void)dismissAnimated:(BOOL)animated cleanup:(BOOL)cleanup
if (self.willDismissHandler) {
self.willDismissHandler(self);
}

if(self.textField) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[self.textField resignFirstResponder];
}

[[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewWillDismissNotification object:self userInfo:nil];
}

Expand Down Expand Up @@ -625,9 +647,10 @@ - (void)validateLayout
NSLog(@"%@, %@", self, NSStringFromSelector(_cmd));
#endif

CGFloat availableHeight = self.bounds.size.height - self.keyboardOffset;
CGFloat height = [self preferredHeight];
CGFloat left = (self.bounds.size.width - CONTAINER_WIDTH) * 0.5;
CGFloat top = (self.bounds.size.height - height) * 0.5;
CGFloat top = (availableHeight - height) * 0.5;
self.containerView.transform = CGAffineTransformIdentity;
self.containerView.frame = CGRectMake(left, top, CONTAINER_WIDTH, height);
self.containerView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.containerView.bounds cornerRadius:self.containerView.layer.cornerRadius].CGPath;
Expand All @@ -648,6 +671,15 @@ - (void)validateLayout
self.messageLabel.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, height);
y += height;
}
if(self.textField) {
if (y > CONTENT_PADDING_TOP) {
y += GAP;
}
CGFloat height = TEXTFIELD_HEIGHT;
self.textField.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, height);
y += height;

}
if (self.items.count > 0) {
if (y > CONTENT_PADDING_TOP) {
y += GAP;
Expand Down Expand Up @@ -687,6 +719,12 @@ - (CGFloat)preferredHeight
}
height += [self heightForMessageLabel];
}
if (self.textField) {
if (height > CONTENT_PADDING_TOP) {
height += GAP;
}
height += TEXTFIELD_HEIGHT;
}
if (self.items.count > 0) {
if (height > CONTENT_PADDING_TOP) {
height += GAP;
Expand Down Expand Up @@ -742,6 +780,9 @@ - (void)setup
[self setupContainerView];
[self updateTitleLabel];
[self updateMessageLabel];
if(self.alertViewStyle == SIAlertViewStylePlainTextInput) {
[self setupTextField];
}
[self setupButtons];
[self invaliadateLayout];
}
Expand Down Expand Up @@ -819,6 +860,23 @@ - (void)updateMessageLabel
[self invaliadateLayout];
}

- (void)setupTextField
{
if(!self.textField) {
self.textField = [[UITextField alloc] initWithFrame:self.bounds];
self.textField.delegate = self;
self.textField.text = @"";
self.textField.borderStyle = UITextBorderStyleBezel;
[self.containerView addSubview:self.textField];
#if DEBUG_LAYOUT
self.textField.backgroundColor = [UIColor redColor];
#endif
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShowNotification:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideNotification:) name:UIKeyboardWillHideNotification object:nil];
}
[self invaliadateLayout];
}

- (void)setupButtons
{
self.buttons = [[NSMutableArray alloc] initWithCapacity:self.items.count];
Expand Down Expand Up @@ -894,6 +952,55 @@ - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
}
}

#pragma mark - UITextField delegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}

#pragma mark - Keyboard notification handlers

-(void)keyboardWillShowNotification:(NSNotification *)notification {
[self moveAlertForKeyboard:notification up:YES];
}
-(void)keyboardWillHideNotification:(NSNotification *)notification {
[self moveAlertForKeyboard:notification up:NO];
}

- (void)moveAlertForKeyboard:(NSNotification*)notification up:(BOOL)up {
NSDictionary* userInfo = [notification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;

[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];

//calculate new position
CGRect containerFrame = self.containerView.frame;
CGRect convertedKeyboardFrame = [self convertRect:keyboardEndFrame fromView:self.window];
CGFloat adjustedHeight = self.bounds.size.height;
if(up) {
adjustedHeight -= convertedKeyboardFrame.size.height;
}
containerFrame.origin.y = (adjustedHeight - containerFrame.size.height) / 2;

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
self.containerView.frame = containerFrame;
[UIView commitAnimations];

//keyboardOffset is used to adjust the alertView y position on willRotate, i.e. before the rotation occurs. Therefore the height is set dependent of the current orientation
if(up) {
self.keyboardOffset = UIInterfaceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? keyboardEndFrame.size.height : keyboardEndFrame.size.width;
} else {
self.keyboardOffset = 0;
}
}

#pragma mark - UIAppearance setters

- (void)setViewBackgroundColor:(UIColor *)viewBackgroundColor
Expand Down
2 changes: 2 additions & 0 deletions SIAlertViewExample/SIAlertViewExample/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ - (IBAction)alert2:(id)sender
- (IBAction)alert3:(id)sender
{
SIAlertView *alertView = [[SIAlertView alloc] initWithTitle:nil andMessage:@"Message3"];
alertView.alertViewStyle = SIAlertViewStylePlainTextInput;
[alertView addButtonWithTitle:@"Cancel"
type:SIAlertViewButtonTypeCancel
handler:^(SIAlertView *alertView) {
Expand All @@ -144,6 +145,7 @@ - (IBAction)alert3:(id)sender
type:SIAlertViewButtonTypeDefault
handler:^(SIAlertView *alertView) {
NSLog(@"OK Clicked");
NSLog(@"Textinput: %@", alertView.inputText);
}];
alertView.transitionStyle = SIAlertViewTransitionStyleDropDown;
alertView.backgroundStyle = SIAlertViewBackgroundStyleSolid;
Expand Down