J'ai ViewController
avec 2 UITextField
éléments: nom d'utilisateur et mot de passe. Je mets délégué pour ces champs, qui comprend le code ci-dessous:
func textFieldShouldReturn(textField: UITextField) -> Bool {
if textField === self.loginField {
self.loginField.resignFirstResponder()
self.passwordField.becomeFirstResponder()
return false
}
return true
}
Cette logique devrait faire passer l'utilisateur du champ de texte de connexion au mot de passe lorsqu'il appuie sur le bouton Suivant du clavier. Mais je suis resté avec le pépin: après
self.passwordField.becomeFirstResponder()
le texte dans le champ de connexion passe au coin supérieur gauche et au dos. Et quoi de plus étrange: ce petit problème ne se reproduit que la première fois, alors vous devez recréer ViewController
pour observer ce comportement
Voici la vidéo du petit problème http://tinypic.com/player.php?v=6nsemw%3E&s=8#.VgVb3cuqpHx
func textFieldShouldReturn(textField: UITextField) -> Bool {
if textField === self.loginField {
self.loginField.resignFirstResponder()
// Shitty workaround. Hi, Apple!
self.loginField.setNeedsLayout()
self.loginField.layoutIfNeeded()
self.passwordField.becomeFirstResponder()
return false
}
return true
}
Sur la base de certaines des idées affichées ici, il s'agit d'une solution facile à mettre en œuvre, qui fonctionne (pour moi) dans tous les cas et ne semble pas avoir d'effets secondaires:
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// Workaround for the jumping text bug.
[textField resignFirstResponder];
[textField layoutIfNeeded];
}
Cette solution fonctionne à la fois si vous passez au champ suivant par programmation à partir de -textFieldShouldReturn:
ou si l'utilisateur touche simplement un autre répondeur.
Dans une sous-classe UITextField
, vous pouvez effectuer les opérations suivantes:
-(BOOL)resignFirstResponder
{
BOOL resigned = [super resignFirstResponder];
[self layoutIfNeeded];
return resigned;
}
Le truc ici est de s’assurer que vous appelez layoutIfNeeded
après que resignFirstResponder
a été appelé.
Le faire de cette façon est très pratique car vous n'avez pas besoin d'appeler vous-même resignFirstResponder
dans les rappels des délégués, car cela m'a causé des problèmes dans un UIScrollView
, mais ce qui précède ne fonctionne pas :)
Utilisez ce code pour éviter le saut de texte dans UITextField.
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
if(textField == self.txtUserName){
[self.txtEmail becomeFirstResponder];
}
else if (textField == self.txtEmail){
[self.txtPassword becomeFirstResponder];
}
else if (textField == self.txtPassword){
[self.txtConfirmPassword becomeFirstResponder];
}
else if (textField == self.txtConfirmPassword){
[self.txtFirstName becomeFirstResponder];
}
else{
[textField resignFirstResponder];
}
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
[textField layoutIfNeeded];
}
func textFieldDidEndEditing(_ textField: UITextField) {
textField.layoutIfNeeded()
}
Je suis aussi confronté au même problème. Le code ci-dessous est travaillé pour moi.
func textFieldDidEndEditing(_ textField: UITextField) {
textField.layoutIfNeeded()
}
Sur la base de ce que je comprends de this :
Ce problème peut survenir lorsque des modifications de disposition ou des animations gérées dans les rappels au clavier affichent et masquent les notifications (généralement lorsque vous souhaitez que le champ de texte soit déplacé de manière à ce que le clavier ne le masque pas).
Solution: Je faisais face à ce problème alors que je faisais layoutIfNeeded à chaque fois que le clavier indiquait qu'on l'appelait en supposant que son coffre-fort était en sécurité.
Une option plus "générique" consiste à utiliser des notifications directement dans votre UITextField sous-classe:
- (void)setupJumpingTextWorkaround {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(forceLayout)
name:UITextFieldTextDidEndEditingNotification object:self];
}
- (void)forceLayout {
[self setNeedsLayout];
[self layoutIfNeeded];
}
N'oubliez pas de vous désabonner
Je ne donne pas mes délégués des champs de texte. Au lieu de cela, je crée une action IBAction et l'attache à l'événement "Did End On Exit". Le problème survient également avec cette méthode, mais uniquement sous iOS 9. Il semble s'agir d'un bogue du système d'exploitation.
Mon action ressemble à ceci:
@IBAction func textFieldAction(sender: UITextField) {
if sender === usernameField {
passwordField.becomeFirstResponder()
}
}
Avec ce qui précède, le problème se produit, mais lorsque je fais le dessous, le problème disparaît:
@IBAction func textFieldAction(sender: UITextField) {
if sender === usernameField {
sender.resignFirstResponder()
passwordField.becomeFirstResponder()
}
}
Je ne semble pas avoir besoin d'appeler setNeedsLayout()
.