如何通过文本字段进行导航(下一个/完成按钮)
如何通过文本字段进行导航(下一个/完成按钮)
我如何在iPhone键盘上使用“下一个”按钮导航所有的文本字段?
最后一个文本字段应该关闭键盘。
我已经设置好IB的按钮(下一个/完成),但现在卡住了。
我实现了textFieldShouldReturn操作,但现在“下一个”和“完成”按钮会关闭键盘。
有一种更加优雅的解决方案第一次看到时让我惊叹不已。好处:
- 更接近于OSX文本字段实现,文本字段知道下一个应该聚焦在哪里
- 不依赖于设置或使用标签 - 在我看来,这种使用情况很脆弱
- 可以扩展为与
UITextField
和UITextView
控件 - 或任何键盘输入UI控件一起使用 - 不会用样板UITextField委托代码给您的视图控制器添乱
- 与IB集成得很好,可以通过熟悉的选项拖放来连接插座进行配置。
创建一个UITextField子类,其中具有名为nextField的IBOutlet
属性。这是标题:
@interface SOTextField : UITextField @property (weak, nonatomic) IBOutlet UITextField *nextField; @end
这是实现:
@implementation SOTextField @end
在您的视图控制器中,您将创建-textFieldShouldReturn:
委托方法:
- (BOOL)textFieldShouldReturn:(UITextField *)textField { if ([textField isKindOfClass:[SOTextField class]]) { UITextField *nextField = [(SOTextField *)textField nextField]; if (nextField) { dispatch_async(dispatch_get_current_queue(), ^{ [nextField becomeFirstResponder]; }); } else { [textField resignFirstResponder]; } } return YES; }
在IB中,更改您的UITextFields以使用SOTextField
类。接下来,在IB中,为每个'SOTextFields'设置代理为“File's Owner”(这就是您放置委托方法 - textFieldShouldReturn代码的位置)。这种设计的优美之处在于,现在您可以简单地右键单击任何textField并将nextField插座分配给您想要成为下一个响应者的下一个SOTextField
对象。
此外,您可以做很酷的事情,例如循环文本字段,以便在最后一个文本字段失去焦点后,第一个文本字段将再次接收焦点。
这可以很容易地扩展到将SOTextField
的returnKeyType
自动分配为UIReturnKeyNext
,如果有下一个字段分配--少一个手动配置的事情。
\n\n在Mac OS X的Cocoa中,你有一个下一个响应者链,在这个链中你可以询问文本字段哪个控件应该成为下一个焦点。这就是使得在文本字段之间使用tab键切换焦点的原因。但是由于iOS设备没有键盘,只有触摸,这个概念在转移到Cocoa Touch时并没有得到保留。\n\n然而这仍然可以通过以下两个假设轻松实现:\n1. 所有可用tab键的UITextField都在同一个父视图上。\n2. 它们的tab顺序由标记属性定义。\n\n如果符合这些假设,你可以通过下面这个方法重写textFieldShouldReturn:\n\n
-(BOOL)textFieldShouldReturn:(UITextField*)textField { NSInteger nextTag = textField.tag + 1; // Try to find next responder UIResponder* nextResponder = [textField.superview viewWithTag:nextTag]; if (nextResponder) { // Found next responder, so set it. [nextResponder becomeFirstResponder]; } else { // Not found, so remove keyboard. [textField resignFirstResponder]; } return NO; // We do not want UITextField to insert line-breaks. }
\n\n如果添加一些更多的代码,那么这些假设也可以忽略掉。\n\nSwift 4.0版本:\n\n
func textFieldShouldReturn(_ textField: UITextField) -> Bool { let nextTag = textField.tag + 1 // Try to find next responder let nextResponder = textField.superview?.viewWithTag(nextTag) as UIResponder! if nextResponder != nil { // Found next responder, so set it nextResponder?.becomeFirstResponder() } else { // Not found, so remove keyboard textField.resignFirstResponder() } return false }
\n\n如果文本字段的父视图是UITableViewCell,则下一个响应者将是:\n\n
let nextResponder = textField.superview?.superview?.superview?.viewWithTag(nextTag) as UIResponder!