Ich entwerfe eine iOS-App und möchte, dass die Rücktaste in meinem iPhone gedrückt wird, um zum nächsten Textfeld zu gelangen.
Ich habe ein paar ähnliche Fragen gefunden, mit hervorragenden Antworten, aber sie sind alle zufällig in Objective-C und ich suche nach Swift-Code. Jetzt habe ich das bisher:
func textFieldShouldReturn(emaillabel: UITextField) -> Bool{
return true
}
Es befindet sich in der Datei, die mit dem UIView verbunden ist, der die Textfelder enthält, und der Controller. Ich bin mir jedoch nicht sicher, ob dies der richtige Ort ist.
Ich bin in Swift grundsätzlich neu, also erkläre jeden kleinen Schritt oder ich schaffe es irgendwie, es durcheinander zu bringen. Ich verwende auch die neueste Version von Xcode, wenn das einen Unterschied macht.
okay, ich habe es ausprobiert und diesen Fehler bekommen://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.
}
Vielen Dank im Voraus, Freunde!
Swift 3.0 (Bearbeitungsverlauf für Vorgängerversionen prüfen):
class ViewController: UIViewController,UITextFieldDelegate
{
//Link each UITextField
@IBOutlet weak var textField: UITextField!
override func viewDidLoad()
{
super.viewDidLoad()
// Do this for each UITextField
textField.delegate = self
textField.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
}
}
Stellen Sie sicher, dass Ihre UITextField
-Delegaten gesetzt sind und die Tags ordnungsgemäß inkrementiert werden. Dies kann auch über den Interface Builder erfolgen.
Hier ist ein Link zu einem Obj-C-Beitrag, den ich gefunden habe: Wie man durch Textfelder navigiert (Next/Done-Buttons)
Swift 4
Sie können leicht zu einem anderen TextField wechseln.
UITextFieldDelegate
hinzu und fügen Sie die textFieldShouldReturn(_:)
-Methode in ViewController hinzu. delegate
-Eigenschaft aus. Hinweis : Dies für alle Textfelder tunErstellen Sie eine IBOutlet
für alle TextFields
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var txtFieldName: UITextField!
@IBOutlet weak var txtFieldEmail: UITextField!
@IBOutlet weak var txtFieldPassword: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - Controlling the Keyboard
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
}
}
Ich schlage vor, dass Sie die switch-Anweisung in textFieldShouldReturn(_:)
verwenden.
// 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
}
Dieser Ansatz erfordert einige Änderungen in den Tabellenansichten und in den Auflistungsansichten, ist aber für einfache Formulare in Ordnung, denke ich.
Verbinden Sie Ihre textFields
mit einer IBOutletCollection
, sortieren Sie sie nach ihrer y-Koordinate und springen Sie in textFieldShouldReturn(_:)
einfach zum nächsten Textfeld, bis Sie das Ende erreichen:
@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
}
Oder schauen Sie sich einfach das Beispielprojekt an (xcode 7 beta 4)
Ich habe viele Codes ausprobiert und dies hat schließlich in Swift 3.0 Latest [March 2017] funktioniert
Die "ViewController" -Klasse sollte das "UITextFieldDelegate" erben, damit dieser Code funktioniert.
class ViewController: UIViewController,UITextFieldDelegate
Fügen Sie das Textfeld mit der richtigen Tag-Nummer hinzu und diese Tag-Nummer wird verwendet, um das Steuerelement auf der Grundlage der ihm zugewiesenen inkrementellen Tag-Nummer in das entsprechende Textfeld zu bringen.
override func viewDidLoad() {
userNameTextField.delegate = self
userNameTextField.tag = 0
userNameTextField.returnKeyType = UIReturnKeyType.next
passwordTextField.delegate = self
passwordTextField.tag = 1
passwordTextField.returnKeyType = UIReturnKeyType.go
}
Im obigen Code, der "returnKeyType = UIReturnKeyType.next", wobei die Rücktaste des Tastenfelds als "Weiter" angezeigt wird, haben Sie auch andere Optionen wie "Join/Go" usw., abhängig von Ihrer Anwendung, die Werte ändert.
Diese "textFieldShouldReturn" ist eine von UITextFieldDelegate gesteuerte Methode. Hier haben wir die nächste Feldauswahl basierend auf der Tag-Wert-Inkrementierung
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
}
der einfachste Weg, zum nächsten Textfeld zu wechseln, besteht darin, dass kein langer Code erforderlich ist
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
}
Caleb's Version in Swift 4.0
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let nextField = self.view.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return false
}
P.S. textField.superview?
funktioniert nicht für mich
Swift 4.2
Dies ist eine allgemeinere und einfachste Lösung. Sie können diesen Code mit einer beliebigen Anzahl von TextFields verwenden. Erben Sie einfach UITextFieldDelegate und aktualisieren Sie das Textfeld-Tag entsprechend der Reihenfolge und kopieren Sie diese Funktion
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
}
Verwenden Sie einfach die becomeFirstResponder()
-Methode der UIResponder-Klasse in Ihrer textFieldShouldReturn
-Methode. Jedes UIView
-Objekt ist eine Unterklasse von UIResponder
.
if self.emaillabel.isEqual(self.anotherTextField)
{
self.anotherTextField.becomeFirstResponder()
}
Weitere Informationen zur becomeFirstResponder()
-Methode finden Sie in hier .
Schnell/Programmatisch
class MyViewController: UIViewController, UITextFieldDelegate {
let textFieldA = UITextField()
let textFieldB = UITextField()
let textFieldC = UITextField()
let textFieldD = UITextField()
var textFields: [UITextField] {
return [textFieldA, textFieldB, textFieldC, textFieldD]
}
override func viewDidLoad() {
// layout textfields somewhere
// then set delegate
textFields.forEach { $0.delegate = self }
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let selectedTextFieldIndex = textFields.firstIndex(of: textField), selectedTextFieldIndex < textFields.count - 1 {
textFields[selectedTextFieldIndex + 1].becomeFirstResponder()
} else {
view.endEditing(true) // last textfield, dismiss keyboard directly
}
return true
}
}
Eine alternative Methode für Puristen, die keine Tags verwenden möchten und der UITextField-Delegat die Zelle sein soll, um die Komponenten getrennt oder unidirektional zu halten.
Erstellen Sie ein neues Protokoll, um die Zellen und den TableViewController zu verbinden.
protocol CellResponder {
func setNextResponder(_ fromCell: UITableViewCell)
}
Fügen Sie das Protokoll Ihrer Zelle hinzu, wobei Ihr TextField-Delegat auch die Zelle ist (ich mache dies im Storyboard).
class MyTableViewCell: UITableViewCell, UITextFieldDelegate {
var responder: CellResponder?
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
responder?.setNextResponder(self)
return true
}
}
Machen Sie Ihren TableViewController mit dem CellResponder-Protokoll (d. H. class MyTableViewController: UITableViewController, CellResponder
) konform und implementieren Sie die Methode nach Ihren Wünschen. Das heißt Wenn Sie unterschiedliche Zelltypen haben, können Sie dies tun. Ebenso können Sie den IndexPath übergeben, ein Tag verwenden usw. Vergessen Sie nicht, cell.responder = self
in cellForRow zu setzen.
func setNextResponder(_ fromCell: UITableViewCell) {
if fromCell is MyTableViewCell, let nextCell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? MySecondTableViewCell {
nextCell.aTextField?.becomeFirstResponder()
} ....
}
Wenn Sie viele Textfeldkomponenten haben, könnte es besser sein, eine Outlet-Sammlung zu verwenden, Textfelder zu verknüpfen und den Return-Schlüssel vom Schnittstellen-Generator festzulegen
@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
}
}
Kein besonderes, hier verwende ich momentan, um das Textfeld zu ändern. Der Code in ViewController sieht also gut aus :). # Swift4
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
}
}
}
Ich habe eine gute Lösung für Ihre Frage.
SCHRITT:
1 - Legen Sie die Rückgabetaste im Storyboard fest.
2 - In Ihrer Swift-Datei.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField.returnKeyType == .next {
Email.resignFirstResponder()
Password.becomeFirstResponder()
} else if textField.returnKeyType == .go {
Password.resignFirstResponder()
self.Login_Action()
}
return true
}
3 - Vergessen Sie nicht, den Delegaten des Textfeldes festzulegen.
Vielen Dank :)