我想知道为什么我的UITextField打开的iPhone键盘除了删除键和文本字段内的清除按钮之外没有输入任何内容。文本字段嵌入在UIActionSheet中,其中包含以下代码示例:
// setup UITextField for the UIActionSheet
UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(8.0, 34.0, 304.0, 30.0)];
NSString* startText = [[self.pathName lastPathComponent] stringByDeletingPathExtension];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.backgroundColor = [UIColor whiteColor];
textField.clearButtonMode = UITextFieldViewModeAlways;
textField.text = startText;
textField.delegate = self;
[textField setKeyboardType:UIKeyboardTypeAlphabet];
[textField setKeyboardAppearance:UIKeyboardAppearanceAlert];
// setup UIActionSheet
UIActionSheet* asheet = [[UIActionSheet alloc] initWithTitle: @"Please enter file name\n\n\n"
delegate: self
cancelButtonTitle: @"Cancel"
destructiveButtonTitle: nil
otherButtonTitles: @"OK", nil];
if ([currentView isKindOfClass:[UIToolbar class]])
[asheet showFromToolbar:(UIToolbar*)currentView];
else if ([currentView isKindOfClass:[UITabBar class]])
[asheet showFromTabBar:(UITabBar*)currentView];
else
[asheet showInView:currentView];
[asheet setFrame:CGRectMake(0.0, 60.0, 320.0, 380.0)];
[asheet insertSubview:textField atIndex:0];
[textField becomeFirstResponder];
// memory management
[textField release];
[asheet release];
我可以按下shift键,但键不会改为小写,它们总是大写的。好吧,我从未使用过带有操作表的文本字段......我在这里做错了什么?行动表和文本字段的委托方法似乎根据需要存在。
修改 我已经更改了操作表的视图关联和操作表的大小:
UIWindow* appWindow = [UIApplication sharedApplication].keyWindow;
[asheet showInView:appWindow];
[asheet setFrame:CGRectMake(0.0, 60.0, 320.0, 204.0)];
while (CGRectEqualToRect(asheet.bounds, CGRectZero))
;
// Add the text field to action sheet
[asheet addSubview:textField];
[textField release];
现在键盘没有被操作表重叠(或“重叠不足”),操作表正确显示在状态栏和导航栏下方,键盘位于操作表下方,自下而上。
但只有 textFieldShouldBeginEditing 和 textFieldDidBeginEditing 才能调用文本字段的委托方法,仅此而已。当我点击它时,Shift键会改变,擦除键可以工作,所有其他键都可以自动显示 - 但不要插入文本字段。那么,它到底是什么?
解决方案: 感谢SVD指出我似乎不可能将UITextField嵌入到UIActionSheet中。因为我想要一个方法来返回带有操作表的文件名字符串(因为我喜欢外观而不是添加了文本字段的UIAlertView)我已经花了更多的工作并最终找到了一个有效的解决方案。我在这里分享,因为我意识到你们中有很多人在寻找类似的东西。
要使这项工作有两个主要方面需要考虑:
文本字段不能是操作表的子视图,至少在 它处于可编辑状态的时刻
操作表不应与键盘重叠
好的,代码来了。模态解决方案适用于第二个runloop,因此可以处理文本字段和操作表的委托方法,无需返回调用者 - 我确信这可以分解为传统方法,您可以在其中处理所有委托内容你自己的班级。
ModalAction.h:
#import <UIKit/UIKit.h>
@interface ModalAction : NSObject
+ (NSString*)ask: (NSString*)question
withTextPrompt: (NSString*)prompt
textPreset: (NSString*)preset
dockToView: (UIView*)toView;
@end
ModalAction.m:
#import "ModalAction.h"
#define TEXT_FIELD_TAG 9999
#define ACTION_SHEET_TAG 8888
@interface ModalActionDelegate : NSObject <UIActionSheetDelegate, UITextFieldDelegate>
{
CFRunLoopRef currentLoop;
NSString* text;
NSUInteger index;
}
@property (assign) NSUInteger index;
@property (retain) NSString* text;
@end
@implementation ModalActionDelegate
@synthesize index;
@synthesize text;
-(id)initWithRunLoop: (CFRunLoopRef)runLoop
{
if (self = [super init])
currentLoop = runLoop;
return self;
}
// Activate keyboard
- (void)acceptInput: (UIActionSheet*)actionSheet
{
UITextField* textField = (UITextField*)[actionSheet viewWithTag:TEXT_FIELD_TAG];
UIWindow* appWindow = [UIApplication sharedApplication].keyWindow;
CGRect frame = textField.frame;
[appWindow insertSubview:textField aboveSubview:actionSheet];
frame.origin.y += 60.0; // move text field to same position as on action sheet
textField.frame = frame;
[textField becomeFirstResponder];
}
- (void)dealloc
{
self.text = nil;
[super dealloc];
}
#pragma mark -
#pragma mark === UIActionSheetDelegate ===
#pragma mark -
// User pressed button. Retrieve results
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(@"actionSheet clickedButtonAtIndex:%d", buttonIndex);
UIWindow* appWindow = [UIApplication sharedApplication].keyWindow;
UITextField* textField = (UITextField*)[appWindow viewWithTag:TEXT_FIELD_TAG];
if (textField != nil)
self.text = textField.text;
self.index = buttonIndex;
CFRunLoopStop(currentLoop);
}
#pragma mark -
#pragma mark === UITextFieldDelegate ===
#pragma mark -
- (BOOL)textFieldShouldBeginEditing:(UITextField*)textField
{
NSLog(@"textFieldShouldBeginEditing");
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField*)textField
{
NSLog(@"textFieldDidBeginEditing");
[textField becomeFirstResponder];
}
- (BOOL)textFieldShouldEndEditing:(UITextField*)textField
{
NSLog(@"textFieldShouldEndEditing");
return YES;
}
- (void)textFieldDidEndEditing:(UITextField*)textField
{
NSLog(@"textFieldDidEndEditing");
[textField resignFirstResponder];
}
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string
{
return YES;
}
- (BOOL)textFieldShouldClear:(UITextField*)textField
{
NSLog(@"textFieldShouldClearEditing");
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
NSLog(@"textFieldShouldReturn (%@)", textField.text);
BOOL hasSomeText = ![textField.text isEqualToString:@""];
if (hasSomeText)
{
// send an OK to the action sheet
UIWindow* appWindow = [UIApplication sharedApplication].keyWindow;
UIActionSheet* actionSheet = (UIActionSheet*)[appWindow viewWithTag:ACTION_SHEET_TAG];
if (actionSheet != nil)
{
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
self.text = textField.text;
self.index = 0;
CFRunLoopStop(currentLoop);
[textField resignFirstResponder];
}
}
return hasSomeText;
}
@end
@implementation ModalAction
+ (NSString*)textQueryWith: (NSString*)question
prompt: (NSString*)prompt
textPreset: (NSString*)preset
button1: (NSString*)button1
button2: (NSString*)button2
forView: (UIView*)toView
{
// Create action sheet
CFRunLoopRef currentLoop = CFRunLoopGetCurrent();
ModalActionDelegate* madelegate = [[ModalActionDelegate alloc] initWithRunLoop:currentLoop];
NSString* sheetTitle = [question stringByAppendingString:@"\n\n\n"];
UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle: sheetTitle
delegate: madelegate
cancelButtonTitle: button1
destructiveButtonTitle: nil
otherButtonTitles: button2, nil];
actionSheet.tag = ACTION_SHEET_TAG;
// Build text field
UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(8.0, 34.0, 304.0, 30.0)];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.tag = TEXT_FIELD_TAG;
textField.placeholder = prompt;
textField.text = preset;
textField.delegate = madelegate;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.keyboardType = UIKeyboardTypeAlphabet;
textField.keyboardAppearance = UIKeyboardAppearanceAlert;
textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
textField.returnKeyType = UIReturnKeyDone;
// Show action sheet and wait for it to finish displaying
UIWindow* appWindow = [UIApplication sharedApplication].keyWindow;
[actionSheet showInView:appWindow];
[actionSheet setFrame:CGRectMake(0.0, 60.0, 320.0, 204.0)];
while (CGRectEqualToRect(actionSheet.bounds, CGRectZero))
;
// Add the text field to action sheet
[actionSheet addSubview:textField];
[textField release];
// Set the field to first responder and move it into place
[madelegate performSelector: @selector(acceptInput:) withObject: actionSheet];
// Start the run loop
CFRunLoopRun();
// Retrieve the user choices
NSUInteger index = madelegate.index;
NSString* answer = [[madelegate.text copy] autorelease];
if (index == 1)
answer = nil; // assumes cancel in position 1
[textField resignFirstResponder];
[actionSheet release];
textField.delegate = nil;
[textField removeFromSuperview];
[madelegate release];
return answer;
}
+ (NSString*)ask: (NSString*)question
withTextPrompt: (NSString*)prompt
textPreset: (NSString*)preset
dockToView: (UIView*)toView
{
return [ModalAction textQueryWith: question
prompt: prompt
textPreset: preset
button1: NSLocalizedString(@"AlertBtnCancel", @"")
button2: @"OK"
forView: toView];
}
@end
它在模拟器iOS 4.2和真实设备的iOS 4.0.2上运行 - 我希望它对其他人也有帮助。
答案 0 :(得分:2)
关于操作表的一个奇怪之处在于,例如,如果存在标签栏,标签栏可能会“窃取”某些操作表单击,即使可视化操作表位于顶部。
您的操作表高度为380像素 - 因此当键盘滑出时,它会与操作表重叠。也许在这种情况下,是操作表窃取键盘的水龙头?尝试使操作表更小,更靠近顶部 - 例如为了测试这个想法,我只是让它起源于0,0和240像素高。
编辑:
显然这是一个问题 - 它对我来说不适用于简单的测试应用程序,没有标签栏或工具栏。我发现了这些链接:
使用警报视图执行此操作似乎有效(尽管它似乎只适用于警报视图): http://discussions.info.apple.com/thread.jspa?threadID=1674641&start=0&tstart=0
而这里有人制作了自己的“行动表”: how to enable text input in UITextField which is in UIActionSheet?