【发布时间】:2009-06-14 05:49:17
【问题描述】:
我使用“返回键”的“下一步”值来获取“下一步”按钮代替“完成”按钮,但(显然)按下它不会自动移动到我视图中的下一个 UITextField。
这样做的正确方法是什么?在一个更大的话题上,在 iPhone SDK 中正确构建表单有哪些技巧?
【问题讨论】:
-
要将答案标记为正确,只需单击答案旁边的空白复选标记图标...
标签: iphone
我使用“返回键”的“下一步”值来获取“下一步”按钮代替“完成”按钮,但(显然)按下它不会自动移动到我视图中的下一个 UITextField。
这样做的正确方法是什么?在一个更大的话题上,在 iPhone SDK 中正确构建表单有哪些技巧?
【问题讨论】:
标签: iphone
使某个对象成为第一个文本字段的委托,并实现- (BOOL)textFieldShouldReturn:(UITextField *)textField 方法;在那里,调用第二个文本字段的-becomeFirstResponder。从中返回YES 将使文本字段执行其返回按钮的默认行为——我认为这通常是发送其操作消息。如果您没有添加任何内容作为该操作的目标,那么您返回的内容并不重要。
【讨论】:
以 Noah 的回答为基础,如果您有很多文本字段并且不想拥有一堆 if,您可以这样做:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
//[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
UIView *view = [self.view viewWithTag:textField.tag + 1];
if (!view)
[textField resignFirstResponder];
else
[view becomeFirstResponder];
return YES;
}
一旦您从任意数字开始标记每个文本字段,只要它们在情节提要或代码中按顺序标记,它应该可以工作。
【讨论】:
UIView *view = [self.view viewWithTag:textField.tag + 1]; if (!view) [textField resignFirstResponder]; else [view becomeFirstResponder];
对于斯威夫特:
func textFieldShouldReturn(textField: UITextField) -> Bool {
//your collection of textfields
guard let i = textFields.indexOf(textField) else { return false }
if i + 1 < textFields.count {
textFields[i + 1].becomeFirstResponder()
return true
}
textField.resignFirstResponder()
return true
}
【讨论】:
这似乎工作得很好,不需要许多人建议的标签系统。不过,此解决方案有两点需要注意:
UITextFields 需要在界面构建器中以正确的顺序排列。
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
/*
* 1. Loop through the textfield's superview
* 2. Get the next textfield in the superview
* 3. Focus that textfield
*/
UIView *superView = [textField superview];
BOOL foundCurrent = false;
for (UITextField *tf in superView.subviews) {
// Set focus on the next textfield
if (foundCurrent) {
[tf becomeFirstResponder];
return NO;
}
//Find current textfield
if ([tf isEqual:textField]) {
foundCurrent = true;
}
}
return YES;
}
【讨论】:
我不喜欢处理标签,所以这是我的解决方案。在您的ViewController 中创建一个包含所有文本字段的IBOutletCollection,拖动以从上到下依次连接您的文本字段。
@interface ViewController () <UITextFieldDelegate>
@property (strong, nonatomic) IBOutletCollection(UITextField) NSArray *allTextFields;
@end
在 viewDidLoad 中设置您的 textFields 委托。 (或将其设置在情节提要中)。
for (VVTextField *tf in self.allTextFields) {
tf.delegate = self;
}
然后实现 UITextField Delegate
#pragma mark - UITextField Delegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSUInteger currentIndex = [self.allTextFields indexOfObject:textField];
NSUInteger nextIndex = currentIndex+1;
if (nextIndex < self.allTextFields.count) {
[[self.allTextFields objectAtIndex:nextIndex] becomeFirstResponder];
} else {
[[self.allTextFields objectAtIndex:currentIndex] resignFirstResponder];
}
return YES;
}
【讨论】:
IBOutletCollection 数组中的对象顺序正确。
我也一直在努力解决这个问题……因此,我创建了用于处理多个文本字段的小型库。你可以在github上找到它GNKeyboardAwareScrollView#GNTextFieldsManager。
您可以使用文本字段数组对其进行初始化:
NSArray *myTextFields = @[...]; // the order of array matters!
GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithTextFields:myTextFields];
或者通过指定父视图(并为所有视图设置标签):
GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithView:self.view];
希望我对某人有用:)
【讨论】: