問題描述
我想知道為什么由 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 中的鍵盤不輸入任何內容的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!