在 UITextField 上使用“下一个”版本的 Return 按钮移动到下一个 UITextField 的最佳方式
Posted
技术标签:
【中文标题】在 UITextField 上使用“下一个”版本的 Return 按钮移动到下一个 UITextField 的最佳方式【英文标题】:Best way to use "Next" version of Return button on UITextField to move to next UITextField 【发布时间】:2009-06-14 05:49:17 【问题描述】:我使用“返回键”的“下一步”值来获取“下一步”按钮代替“完成”按钮,但(显然)按下它不会自动移动到我视图中的下一个 UITextField。
这样做的正确方法是什么?在一个更大的话题上,在 iPhone SDK 中正确构建表单有哪些技巧?
【问题讨论】:
要将答案标记为正确,只需单击答案旁边的空白复选标记图标... 【参考方案1】:使某个对象成为第一个文本字段的委托,并实现- (BOOL)textFieldShouldReturn:(UITextField *)textField
方法;在那里,调用第二个文本字段的-becomeFirstResponder
。从中返回YES
将使文本字段执行其返回按钮的默认行为——我认为这通常是发送其操作消息。如果您没有添加任何内容作为该操作的目标,那么您返回的内容并不重要。
【讨论】:
...如果你在最后一个 UITextField 你应该调用 resignFirstResponder 来隐藏键盘。 这是与此处解释的完全不同的方式 (***.com/questions/467881/…) 还是两者都可以正常工作? 两者都可以。我的回答使用委托系统,布拉德是目标行动的东西。 与纯文本相比,示例代码几乎总是更好。 感谢您的建议,Engin。【参考方案2】:以 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;
一旦您从任意数字开始标记每个文本字段,只要它们在情节提要或代码中按顺序标记,它应该可以工作。
【讨论】:
很好的解决方案!一项(次要)建议调整 - 测试 viewWithTag == nil:UIView *view = [self.view viewWithTag:textField.tag + 1]; if (!view) [textField resignFirstResponder]; else [view becomeFirstResponder];
【参考方案3】:
对于斯威夫特:
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
【讨论】:
【参考方案4】:这似乎工作得很好,不需要许多人建议的标签系统。不过,此解决方案有两点需要注意:
所有 UITextFields 必须在同一个 UIView 中(具有相同的 superview)。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;
【讨论】:
【参考方案5】:我不喜欢处理标签,所以这是我的解决方案。在您的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
数组中的对象顺序正确。
@JAL 有一个很好的观点。您应该考虑编辑您的答案或以某种方式映射值。这可能会导致意外行为。【参考方案6】:
我也一直在努力解决这个问题……因此,我创建了用于处理多个文本字段的小型库。你可以在github上找到它GNKeyboardAwareScrollView#GNTextFieldsManager。
您可以使用文本字段数组对其进行初始化:
NSArray *myTextFields = @[...]; // the order of array matters!
GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithTextFields:myTextFields];
或者通过指定父视图(并为所有视图设置标签):
GNTextFieldsManager *manager = [[GNTextFieldsManager alloc] initWithView:self.view];
希望我对某人有用:)
【讨论】:
以上是关于在 UITextField 上使用“下一个”版本的 Return 按钮移动到下一个 UITextField 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章
按下返回键时如何在下一个 UITextField 上移动控件
UITextField - 检测内置 iPhone 键盘上的输入?