我正在设计一个iOS应用程序,我希望在我的iPhone中按下返回键时,它会将我引导到下一个文本字段。
我发现了几个类似的问题,并且有很好的答案,但它们恰好都在Objective-C中,我正在寻找Swift代码,现在这就是我现在所拥有的:
func textFieldShouldReturn(emaillabel: UITextField) -> Bool{
return true
}
它被放置在连接的文件和包含文本字段的UIView的控制器中,但我不确定这是不是正确的地方。
我基本上是Swift的新手,所以解释每一个小步骤,否则我会设法弄乱它。此外,我正在使用最新版本的Xcode,如果这有任何区别。
好的,所以我尝试了这个并得到了这个错误:
//could not find an overload for '!=' that accepts the supplied arguments
func textFieldShouldReturn(textField: UITextField) -> Bool {
let nextTag: NSInteger = textField.tag + 1
// Try to find next responder
let nextResponder: UIResponder = textField.superview!.viewWithTag(nextTag)!
if (nextResponder != nil) {
// could not find an overload for '!=' that accepts the supplied arguments
// Found next responder, so set it.
nextResponder.becomeFirstResponder()
} else {
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
return false // We do not want UITextField to insert line-breaks.
}
在此先感谢好朋友!
确保您的UITextField
代表已设置且标签正确递增。这也可以通过Interface Builder完成。
这是我发现的Obj-C帖子的链接:How to navigate through textfields (Next / Done Buttons)
class ViewController: UIViewController,UITextFieldDelegate {
// Link each UITextField (Not necessary if delegate and tag are set in Interface Builder)
@IBOutlet weak var someTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do the next two lines for each UITextField here or in the Interface Builder
someTextField.delegate = self
someTextField.tag = 0 //Increment accordingly
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Try to find next responder
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
// Do not add a line break
return false
}
}
不喜欢使用标签的纯粹主义者的另一种方法,并希望UITextField委托成为保持组件分离或单向的单元格...
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
let txtTag:Int = textField.tag
if let textFieldNxt = self.view.viewWithTag(txtTag+1) as? UITextField {
textFieldNxt.becomeFirstResponder()
}else{
textField.resignFirstResponder()
}
return true
}
protocol CellResponder {
func setNextResponder(_ fromCell: UITableViewCell)
}
)并根据需要实现该方法。即如果你有不同的单元格类型,那么你可以这样做,同样你可以传入IndexPath,使用标签等。不要忘记在cellForRow中设置class MyTableViewCell: UITableViewCell, UITextFieldDelegate {
var responder: CellResponder?
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
responder?.setNextResponder(self)
return true
}
}
..
class MyTableViewController: UITableViewController, CellResponder
没有什么特别的,这是我目前用来改变文字字段。 ViewController中的代码看起来不错:)。 #Swift4
cell.responder = self
如果你有很多文本字段组件可能是最好使用插座集合,链接文本字段和从界面构建器设置返回键
func setNextResponder(_ fromCell: UITableViewCell) {
if fromCell is MyTableViewCell, let nextCell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? MySecondTableViewCell {
nextCell.aTextField?.becomeFirstResponder()
} ....
}
我对你的问题有一个很好的解决方案。
步:
1 - 从故事板中设置返回键。
final class SomeTextFiled: UITextField {
public var actionKeyboardReturn: (() -> ())?
override init(frame: CGRect) {
super.init(frame: frame)
super.delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
fatalError("init(coder:) has not been implemented")
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.resignFirstResponder()
actionKeyboardReturn?()
return true
}
}
extension SomeTextFiled: UITextFieldDelegate {}
class MyViewController : UIViewController {
var tfName: SomeTextFiled!
var tfEmail: SomeTextFiled!
var tfPassword: SomeTextFiled!
override func viewDidLoad() {
super.viewDidLoad()
tfName = SomeTextFiled(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
tfName.actionKeyboardReturn = { [weak self] in
self?.tfEmail.becomeFirstResponder()
}
tfEmail = SomeTextFiled(frame: CGRect(x: 100, y: 0, width: 100, height: 100))
tfEmail.actionKeyboardReturn = { [weak self] in
self?.tfPassword.becomeFirstResponder()
}
tfPassword = SomeTextFiled(frame: CGRect(x: 200, y: 0, width: 100, height: 100))
tfPassword.actionKeyboardReturn = {
/// Do some further code
}
}
}
2 - 在你的swift文件中。
@IBOutlet var formTextFields: [UITextField]!
override func viewDidLoad() {
for textField in formTextFields {
textField.delegate = self
}
}
extension RegisterViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let componentIndex = formTextFields.firstIndex(of: textField) {
if textField.returnKeyType == .next,
componentIndex < (formTextFields.count - 1) {
formTextFields[componentIndex + 1].becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
}
return true
}
}
3 - 不要忘记设置Textfield的代理。
谢谢 :)
斯威夫特5
在键盘上单击返回键时,可以轻松切换到另一个TextField。
UITextFieldDelegate
并在ViewController中添加textFieldShouldReturn(_:)
委托方法delegate
选项。注意:对所有TextField执行此操作我建议你应该在IBOutlet
中使用switch语句。
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var txtFieldName: UITextField!
@IBOutlet weak var txtFieldEmail: UITextField!
@IBOutlet weak var txtFieldPassword: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == txtFieldName {
textField.resignFirstResponder()
txtFieldEmail.becomeFirstResponder()
} else if textField == txtFieldEmail {
textField.resignFirstResponder()
txtFieldPassword.becomeFirstResponder()
} else if textField == txtFieldPassword {
textField.resignFirstResponder()
}
return true
}
}
这种方法需要在表视图和集合视图中进行一些更改,但我认为它对于简单的表单是可以的。
将你的textFieldShouldReturn(_:)
连接到一个// MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
switch textField {
case nameTextField:
phoneTextField.becomeFirstResponder()
case phoneTextField:
emailTextField.becomeFirstResponder()
case emailTextField:
descriptionTextField.becomeFirstResponder()
default:
textField.resignFirstResponder()
}
return false
}
,按y坐标排序,然后在textFields
中跳转到下一个文本域,直到你到达结尾:
IBOutletCollection
或者只看一下textFieldShouldReturn(_:)
(xcode 7 beta 4)
我尝试过很多代码,最后这个在Swift 3.0中为我工作最新[2017年3月]
“ViewController”类应继承“UITextFieldDelegate”以使此代码正常工作。
@IBOutlet var textFields: [UITextField]!
...
textFields.sortInPlace { $0.frame.origin.y < $1.frame.origin.y }
...
func textFieldShouldReturn(textField: UITextField) -> Bool {
if let currentIndex = textFields.indexOf(textField) where currentIndex < textFields.count-1 {
textFields[currentIndex+1].becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return true
}
添加带有正确标记号的文本字段,此标记号用于根据分配给它的增量标记号将控件转移到适当的文本字段。
sample project
在上面的代码中,“returnKeyType = UIReturnKeyType.next”将使键盘返回键显示为“Next”,您还可以根据应用程序更改值等其他选项“Join / Go”等。
这个“textFieldShouldReturn”是一个UITextFieldDelegate控制的方法,这里我们根据Tag值增量进行下一个字段选择
class ViewController: UIViewController,UITextFieldDelegate
更改为下一个文本的最简单方法字段是不需要长代码
override func viewDidLoad() {
userNameTextField.delegate = self
userNameTextField.tag = 0
userNameTextField.returnKeyType = UIReturnKeyType.next
passwordTextField.delegate = self
passwordTextField.tag = 1
passwordTextField.returnKeyType = UIReturnKeyType.go
}
Caleb在Swift 4.0中的版本
func textFieldShouldReturn(_ textField: UITextField) -> Bool
{
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
textField.resignFirstResponder()
return true;
}
return false
}
附: override func viewDidLoad() {
super.viewDidLoad()
emailTextField.delegate = self
passwordTextField.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == emailTextField {
passwordTextField.becomeFirstResponder()
}else {
passwordTextField.resignFirstResponder()
}
return true
}
不适合我
只需在func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let nextField = self.view.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return false
}
方法中使用UIResponder类的textField.superview?
方法。每个becomeFirstResponder()
对象都是textFieldShouldReturn
的子类。
UIView
您可以在UIResponder
的Apple Doc's找到有关if self.emaillabel.isEqual(self.anotherTextField)
{
self.anotherTextField.becomeFirstResponder()
}
方法的更多信息。
Swift 4.2
这是一个更通用,最简单的解决方案,您可以将此代码与任意数量的TextFields一起使用。只需继承UITextFieldDelegate并根据顺序更新Textfield标签并复制此功能
becomeFirstResponder()