我想知道为什么由 UITextField 打开的 iPhone 键盘除了文本字段本身内的删除键和清除按钮之外没有输入任何内容.文本字段嵌入在带有此代码示例的 UIActionSheet 中:
I'm wondering why my iPhone keyboard opened by a UITextField doesn't type anything except the delete key and the clear button within the text field itself. The text field is embedded in a UIActionSheet with this code sample:
// 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
"
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 键,但键不会变成小写,它们总是大写.好吧,我从来没有使用带有操作表的文本字段......我在这里做错了什么?操作表和文本字段的委托方法似乎根据需要存在.
I can press the shift key but the keys don't change to lowercase, they are always uppercase. Well, I have never used a text field with an action sheet ... what am I doing wrong here? The delegate methods for action sheet and text field seem to be present as needed.
我还更改了操作表的视图关联和操作表的大小:
I've changed the view association of the action sheet and the size of the action sheet as well:
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];
现在键盘没有被操作表重叠(或underlapped"),操作表正确显示在状态栏和导航栏下方,键盘跟随在操作表下方并自下而上.
Now the keyboard is not overlapped (or "underlapped") by the action sheet, the action sheet shows properly below status bar and navigation bar and the keyboard follows below the action sheet and comes from bottom up.
但只有 textFieldShouldBeginEditing 和 textFieldDidBeginEditing 会调用文本字段的委托方法,仅此而已.当我点击它时,Shift键会改变,擦除键有效,所有其他键都会在点击时显示出来 - 但不要插入文本字段.那么,这到底是怎么回事?
But only textFieldShouldBeginEditing and textFieldDidBeginEditing get called of the text field's delegate methods, nothing more. The shift key changes when I tap it, the erase key works, all other keys show themselves on tap - but don't insert into the text field. So, what is it all about?
解决方案:感谢 SVD 向我指出似乎不可能将 UITextField 嵌入 UIActionSheet 的事实.因为我想要一个方法来返回带有操作表的文件名字符串(只是因为我更喜欢外观而不是添加了文本字段的 UIAlertView),所以我花了更多的工作,终于找到了一个可行的解决方案.我在这里分享它是因为我意识到你们中的很多人都在寻找类似的东西.
Solution: Thanks to SVD pointing me to the fact that it doesn't seem to be possible to embed a UITextField into a UIActionSheet. Because I want to have a method that returns a file name string with an action sheet (just because I like the appearance more than a UIAlertView with a text field added) I've spent some more work on it and finally found a working solution. I share it here because I realized that quite a lot of you were looking for a similar thing.
要使其发挥作用,需要考虑两个主要方面:
There are two main aspects to consider to get this working:
文本字段不能是操作表的子视图,至少在处于可编辑状态的时刻
the text field must not be a subview of the action sheet, at least at the moment when it is in editable state
操作表不应与键盘重叠
好的,代码来了.模态解决方案与第二个运行循环一起使用,因此可以在不返回调用者的情况下处理文本字段和操作表的委托方法 - 我确信这可以分解为处理所有委托内容的传统方法你自己的班级.
Ok, here comes the code. The modal solution works with a second runloop, so the delegate methods for text field and action sheet can be handled w/out returning to the caller - I'm sure this can be broken down into the conventional approach where you handle all delegate stuff within your own class.
ModalAction.h:
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:
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:@"
"];
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 上运行 - 我希望它对其他人也有帮助.
It is running on Simulator iOS 4.2 and on real devices' iOS 4.0.2 - I hope it is also helpful for others.
关于操作表的一个奇怪的事情是,例如,如果存在标签栏,标签栏可能会窃取"一些操作表点击,即使在视觉上操作表在顶部.
One weird thing about action sheets is that, for example, if there's a tab bar present, the tab bar may "steal" some of the action sheets taps, even though visually the action sheet is on top.
您的操作表是 380 像素高 - 因此当键盘滑出时,它会与操作表重叠.也许在这种情况下,是动作表偷走了键盘的敲击声?尝试使操作表更小更靠近顶部 - 例如为了测试这个想法,我只是让它起源于 0,0 和 240 像素高.
Your action sheet is 380 pixels high - so when the keyboard slides out it overlaps with the action sheet. Perhaps in this case it is the action sheet stealing the keyboard's taps? Try making the action sheet smaller and closer to the top - e.g. to test the idea I'd just make it originate at 0,0, and 240 pixels high.
显然这是一个问题 - 在没有标签栏或工具栏的简单测试应用程序中,它对我不起作用.我找到了这些链接:
Apparently it is a problem - it doesn't work for me either in a simple test application, without tab bar or tool bar. I've found these links though:
使用警报视图执行此操作,它似乎有效(尽管它似乎只适用于警报视图):https://discussions.apple.com/thread/1674641
Doing this with an alert view and it seems to work (although it seems like it only works for alert views): https://discussions.apple.com/thread/1674641
这里有人制作了自己的行动表":如何在 UITextField 中启用文本输入UIActionSheet?
And here someone making their own "action sheet" instead: how to enable text input in UITextField which is in UIActionSheet?
这篇关于UIActionSheet 中的键盘不输入任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!