Add TextField or other control to UIActionSheet or UIAlertView
Please help.
Thanks
iPhone, Other OS, iphone development
iPhone, Other OS, iphone development
UIActionSheet *actionSheet;
// allocate, init, etc.
// loop through each subview
for (id subview in actionSheet.subviews) {
// write to the log what the subview is
NSLog(@"Subview is a %@", [subview description]);
// hide all buttons
if ([subview isKindOfClass:[UIButton class]])
subview.hidden = YES;
}
TextAlertView *alert = [[TextAlertView alloc] initWithTitle:@"Some Title"
message:@"Some Message - also multiline or nil"
delegate:self cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK", nil];
alert.textField.keyboardType = UIKeyboardTypeNumberPad;
// tag the alert in case you have multiple alert sheet calls
alert.tag = 1;
[alert show];
[alert release];
/*
* UIAlertView/TextAlertView delegate method(s)
*/
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
TextAlertView *alertView = (TextAlertView*) actionSheet;
if(buttonIndex > 0) {
if(alertView.tag == 1) {
NSString *textValue = alertView.textField.text;
if(textValue==nil)
return;
// do something meaningful with textValue
}
}
}
/*
* Text Alert View
*
* File: TextAlertView.h
* Abstract: UIAlertView extension with UITextField (Interface Declaration).
*
*/
#import <UIKit/UIKit.h>
#define kUITextFieldHeight 30.0
#define kUITextFieldXPadding 12.0
#define kUITextFieldYPadding 10.0
#define kUIAlertOffset 100.0
@interface TextAlertView : UIAlertView {
UITextField *textField;
BOOL layoutDone;
}
@property (nonatomic, retain) UITextField *textField;
- (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...;
@end
/*
* Text Alert View
*
* File: TextAlertView.m
* Abstract: UIAlertView extension with UITextField (Implementation).
*
*/
#import "TextAlertView.h"
@implementation TextAlertView
@synthesize textField;
/*
* Initialize view with maximum of two buttons
*/
- (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... {
self = [super initWithTitle:title message:message delegate:delegate cancelButtonTitle:cancelButtonTitle
otherButtonTitles:otherButtonTitles, nil];
if (self) {
// Create and add UITextField to UIAlertView
UITextField *myTextField = [[[UITextField alloc] initWithFrame:CGRectZero] retain];
myTextField.autocorrectionType = UITextAutocorrectionTypeNo;
myTextField.alpha = 0.75;
myTextField.borderStyle = UITextBorderStyleRoundedRect;
myTextField.delegate = delegate;
[self setTextField:myTextField];
// insert UITextField before first button
BOOL inserted = NO;
for( UIView *view in self.subviews ){
if(!inserted && ![view isKindOfClass:[UILabel class]])
[self insertSubview:myTextField aboveSubview:view];
}
//[self addSubview:myTextField];
// ensure that layout for views is done once
layoutDone = NO;
// add a transform to move the UIAlertView above the keyboard
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0.0, kUIAlertOffset);
[self setTransform:myTransform];
}
return self;
}
/*
* Show alert view and make keyboard visible
*/
- (void) show {
[super show];
[[self textField] becomeFirstResponder];
}
/*
* Determine maximum y-coordinate of UILabel objects. This method assumes that only
* following objects are contained in subview list:
* - UILabel
* - UITextField
* - UIThreePartButton (Private Class)
*/
- (CGFloat) maxLabelYCoordinate {
// Determine maximum y-coordinate of labels
CGFloat maxY = 0;
for( UIView *view in self.subviews ){
if([view isKindOfClass:[UILabel class]]) {
CGRect viewFrame = [view frame];
CGFloat lowerY = viewFrame.origin.y + viewFrame.size.height;
if(lowerY > maxY)
maxY = lowerY;
}
}
return maxY;
}
/*
* Override layoutSubviews to correctly handle the UITextField
*/
- (void)layoutSubviews {
[super layoutSubviews];
CGRect frame = [self frame];
CGFloat alertWidth = frame.size.width;
// Perform layout of subviews just once
if(!layoutDone) {
CGFloat labelMaxY = [self maxLabelYCoordinate];
// Insert UITextField below labels and move other fields down accordingly
for(UIView *view in self.subviews){
if([view isKindOfClass:[UITextField class]]){
CGRect viewFrame = CGRectMake(
kUITextFieldXPadding,
labelMaxY + kUITextFieldYPadding,
alertWidth - 2.0*kUITextFieldXPadding,
kUITextFieldHeight);
[view setFrame:viewFrame];
} else if(![view isKindOfClass:[UILabel class]]) {
CGRect viewFrame = [view frame];
viewFrame.origin.y += kUITextFieldHeight;
[view setFrame:viewFrame];
}
}
// size UIAlertView frame by height of UITextField
frame.size.height += kUITextFieldHeight + 2.0;
[self setFrame:frame];
layoutDone = YES;
} else {
// reduce the x placement and width of the UITextField based on UIAlertView width
for(UIView *view in self.subviews){
if([view isKindOfClass:[UITextField class]]){
CGRect viewFrame = [view frame];
viewFrame.origin.x = kUITextFieldXPadding;
viewFrame.size.width = alertWidth - 2.0*kUITextFieldXPadding;
[view setFrame:viewFrame];
}
}
}
}
@end
@class UITextField, UILabel;
@interface UIAlertView (Extended)
- (UITextField)addTextFieldWithValue:(NSString)value label:(NSString*)label;
- (UITextField*)textFieldAtIndex:(NSUInteger)index;
- (NSUInteger)textFieldCount;
- (UITextField*)textField;
@end
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"My Title"
message:@"My Message"
delegate:self cancelButtonTitle:@"Cancel"
otherButtonTitles:@"OK", nil];
[alert addTextFieldWithValue:@"25" label:nil];
[alert textField].keyboardType = UIKeyboardTypeNumberPad;
alert.tag = kMyAlert;
[alert show];
[alert release];
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex > 0) {
if(actionSheet.tag == kMyAlert) {
NSString *textValue = [actionSheet textField].text;
if(textValue==nil)
return;
NSInteger value = [textValue integerValue];
}
}
}
Add TextField or other control to UIActionSheet or UIAlertView