Avec le SDK iOS:
J'ai un UIView
avec des UITextField
s qui font apparaître un clavier. J'en ai besoin pour pouvoir:
Permet de faire défiler le contenu du
UIScrollView
pour voir les autres champs de texte une fois le clavier levé"Saut" automatique (en faisant défiler vers le haut) ou raccourcissement
Je sais que j'ai besoin d'un UIScrollView
. J'ai essayé de changer la classe de mon UIView
en UIScrollView
mais je ne parviens toujours pas à faire défiler les zones de texte vers le haut ou vers le bas.
Ai-je besoin à la fois d'un UIView
et d'un UIScrollView
? Est-ce que l'un entre dans l'autre?
Que faut-il mettre en œuvre pour faire défiler automatiquement le champ de texte actif?
Idéalement, autant de configuration des composants que possible se fera dans Interface Builder. Je voudrais seulement écrire du code pour ce qui en a besoin.
Remarque: le UIView
(ou UIScrollView
) avec lequel je travaille est affiché par une barre d'onglets ( UITabBar
), qui doit fonctionner normalement.
Edit: j'ajoute la barre de défilement juste au moment où le clavier apparaît. Même si ce n'est pas nécessaire, j'ai l'impression que cela offre une meilleure interface, car l'utilisateur peut faire défiler et modifier les zones de texte, par exemple.
Je l'ai fait fonctionner où je change la taille d'image du UIScrollView
quand le clavier monte et descend. J'utilise simplement:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
//Keyboard becomes visible
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height - 215 + 50); //resize
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
//keyboard will hide
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height + 215 - 50); //resize
}
Cependant, cela ne "monte" pas ou ne centre pas automatiquement les champs de texte inférieurs dans la zone visible, ce que j'aimerais vraiment.
la source
Réponses:
Vous n'en aurez besoin que
ScrollView
si le contenu que vous avez maintenant ne rentre pas dans l'écran de l'iPhone. (Si vous ajoutez leScrollView
comme vue d'ensemble des composants juste pour faireTextField
défiler vers le haut lorsque le clavier apparaît, alors ce n'est pas nécessaire.)La manière standard d'empêcher les
TextField
s d'être couverts par le clavier est de déplacer la vue vers le haut / bas chaque fois que le clavier est affiché.Voici un exemple de code:
la source
textFieldDidBeginEditing
section.J'avais aussi beaucoup de problèmes avec la
UIScrollView
composition de plusieursUITextFields
, dont un ou plusieurs seraient obscurcis par le clavier lors de leur édition.Voici quelques éléments à considérer si votre
UIScrollView
défilement n'est pas correct.1) Assurez-vous que votre contentSize est supérieur à la
UIScrollView
taille du cadre. La façon de comprendreUIScrollViews
est queUIScrollView
c'est comme une fenêtre de visualisation sur le contenu défini dans contentSize. Donc, pour que leUIScrollview
pour faire défiler n'importe où, le contentSize doit être supérieur auUIScrollView
. Sinon, aucun défilement n'est requis car tout ce qui est défini dans contentSize est déjà visible. BTW, contentSize par défaut =CGSizeZero
.2) Maintenant que vous comprenez que
UIScrollView
c'est vraiment une fenêtre sur votre "contenu", la façon de vous assurer que le clavier n'obscurcit pas votreUIScrollView's
"fenêtre" de visualisation serait de redimensionner leUIScrollView
afin que lorsque le clavier est présent, vous avez laUIScrollView
fenêtre dimensionné juste à l'image originaleUIScrollView
frame.size.height moins la hauteur du clavier. Cela garantira que votre fenêtre n'est que cette petite zone visible.3) Voici le problème: lorsque j'ai implémenté cela pour la première fois, j'ai pensé que je devrais obtenir le
CGRect
champ de texte modifié et appeler laUIScrollView's
méthode scrollRecToVisible. J'ai implémenté laUITextFieldDelegate
méthodetextFieldDidBeginEditing
avec l'appel à lascrollRecToVisible
méthode. Cela en fait travaillé avec un effet secondaire étrange que le défilement se casser laUITextField
en position. Pendant longtemps, je n'ai pas pu comprendre ce que c'était. Ensuite, j'ai commenté latextFieldDidBeginEditing
méthode Delegate et tout fonctionne !! (???). En fin de compte, je pense que leUIScrollView
fait implicitement apporte implicitement le contenu actuellement éditéUITextField
dans la fenêtre visible. Mon implémentation de laUITextFieldDelegate
méthode et l'appel subséquent auscrollRecToVisible
étaient redondants et étaient à l'origine de l'étrange effet secondaire.Voici donc les étapes pour faire défiler correctement votre
UITextField
en unUIScrollView
lorsque le clavier apparaît.viewDidLoad
viewDidUnload
contentSize
est réglé et supérieur à votreUIScrollView
àviewDidLoad
UIScrollView
lorsque le clavier est présentUIScrollView
lorsque le clavier disparaît.UITextField
est , même si le onglets clavier est déjà présent pour éviter le rétrécissement duUIScrollView
quand il est déjà rétrécisUne chose à noter est que le
UIKeyboardWillShowNotification
se déclenchera même lorsque le clavier est déjà à l'écran lorsque vous tabulez sur un autreUITextField
. J'ai pris soin de cela en utilisant un ivar pour éviter de redimensionner leUIScrollView
lorsque le clavier est déjà à l'écran. Redimensionner par inadvertanceUIScrollView
le clavier quand il est déjà là serait désastreux!J'espère que ce code vous évitera beaucoup de maux de tête.
la source
UIKeyboardBoundsUserInfoKey
est obsolète. 2. keyboardSize est en "coordonnées d'écran", donc vos calculs viewFrame échoueront si le cadre est tourné ou mis à l'échelle.CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
place du dépréciéUIKeyboardBoundsUserInfoKey
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size
devrait être[[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size
. Grande solution cependant!Il est préférable d'utiliser la mise en œuvre d'Apple, comme indiqué dans la documentation . Cependant, le code qu'ils fournissent est défectueux. Remplacez la partie trouvée
keyboardWasShown:
juste en dessous des commentaires par ce qui suit:Les problèmes avec le code d'Apple sont les suivants: (1) Ils calculent toujours si le point est dans le cadre de la vue, mais c'est un
ScrollView
, il peut donc déjà avoir défilé et vous devez tenir compte de ce décalage:(2) Ils décalent le contentOffset de la hauteur du clavier, mais nous voulons le contraire (nous voulons décaler le
contentOffset
de la hauteur visible à l'écran, pas ce qui ne l'est pas):la source
UIKeyboardFrameEndUserInfoKey
plutôt que d'UIKeyboardFrameBeginUserInfoKey
obtenir la taille du clavier, car cela permettra de détecter des modifications telles que le clavier personnalisé et d'activer / désactiver le texte prédictif.self.scrollView.contentOffset = self.currentSVoffset;
Dans
textFieldDidBeginEditting
et entextFieldDidEndEditing
appelant la fonction[self animateTextField:textField up:YES]
comme ceci:J'espère que ce code vous aidera.
Dans Swift 2
SWIFT 3
la source
[UIView animateWithDuration: animations:^{ }];
?En utilisant simplement TextFields:
1a) Utilisation
Interface Builder
: Sélectionnez Tous les TextFields => Modifier => Incorporer dans => ScrollView1b) Incorporez manuellement TextFields dans UIScrollView appelé scrollView
2) Définir
UITextFieldDelegate
3) Réglez chacun
textField.delegate = self;
(ou établissez des connexionsInterface Builder
)4) Copier / coller:
la source
textField
est déjà visible.CGPointMake(0, textField.frame.origin.y);
pourCGPointMake(0, textField.frame.origin.y + scrollView.contentInset.top);
Pour Universal Solution , voici mon approche pour implémenter IQKeyboardManager .
Etape 1: - J'ai ajouté des notifications globales de
UITextField
,UITextView
etUIKeyboard
dans une classe singleton. Je l'appelle IQKeyboardManager .Étape 2: - Si trouvé
UIKeyboardWillShowNotification
,UITextFieldTextDidBeginEditingNotification
ouUITextViewTextDidBeginEditingNotification
notifications, j'essaye d'obtenir unetopMostViewController
instance de laUIWindow.rootViewController
hiérarchie. Afin de bien le découvrirUITextField
/UITextView
sur celui-ci,topMostViewController.view
le cadre doit être ajusté.Étape 3: - J'ai calculé la distance de déplacement prévue de
topMostViewController.view
par rapport à la première réponseUITextField
/UITextView
.Étape 4: - Je me suis déplacé
topMostViewController.view.frame
vers le haut / bas en fonction de la distance de déplacement attendue.Étape5: - Si trouvé
UIKeyboardWillHideNotification
,UITextFieldTextDidEndEditingNotification
ouUITextViewTextDidEndEditingNotification
notification, j'essaie à nouveau d'obtenir unetopMostViewController
instance de laUIWindow.rootViewController
hiérarchie.Étape 6: - J'ai calculé la distance perturbée
topMostViewController.view
qui doit être restaurée à sa position d'origine.Étape 7: - J'ai rétabli
topMostViewController.view.frame
en fonction de la distance perturbée.Étape 8: - J'ai instancié l' instance de classe IQKeyboardManager singleton lors du chargement de l'application, de sorte que chaque
UITextField
/UITextView
dans l'application s'ajustera automatiquement en fonction de la distance de déplacement attendue.C'est tout ce que IQKeyboardManager fait pour vous avec AUCUNE LIGNE DE CODE vraiment !! il suffit de glisser-déposer le fichier source associé pour projeter. IQKeyboardManager prend également en charge l' orientation des périphériques , la gestion automatique de la barre d'outils UIT , KeybkeyboardDistanceFromTextField et bien plus que vous ne le pensez.
la source
Je l' ai mis en place un universel, sans rendez- vous
UIScrollView
,UITableView
et mêmeUICollectionView
sous - classe qui prend soin de déplacer tous les champs de texte dans ce hors du chemin du clavier.Lorsque le clavier est sur le point d'apparaître, la sous-classe trouvera la sous-vue qui est sur le point d'être modifiée et ajustera son décalage de cadre et de contenu pour s'assurer que la vue est visible, avec une animation correspondant à la fenêtre contextuelle du clavier. Lorsque le clavier disparaît, il restaure sa taille précédente.
Il devrait fonctionner avec pratiquement n'importe quelle configuration, soit une
UITableView
interface basée sur une interface, soit une interface composée de vues placées manuellement.Voici: solution pour déplacer les champs de texte hors du chemin du clavier
la source
Cela fera tout pour vous, mettez-les simplement dans votre classe de contrôleur de vue et implémentez le
UITextFieldDelegate
à votre contrôleur de vue et définissez le délégué de textField surself
Implémentez les méthodes de rappel des délégués:
Pour Swift 4, 4.2, 5: Modifier
à
Dernière remarque sur cette implémentation: si vous poussez un autre contrôleur de vue sur la pile pendant que le clavier est affiché, cela créera une erreur où la vue reviendra à son cadre central mais le décalage du clavier ne sera pas réinitialisé. Par exemple, votre clavier est le premier répondeur de nameField, mais vous appuyez ensuite sur un bouton qui pousse votre Help View Controller sur votre pile. Pour corriger l'erreur de décalage, assurez-vous d'appeler nameField.resignFirstResponder () avant de quitter le contrôleur de vue, en vous assurant que la méthode déléguée textFieldDidEndEditing est également appelée. Je le fais dans la méthode viewWillDisappear.
la source
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
donc j'ai changé cette ligne enself.view.frame.offsetInPlace(dx: 0, dy: movement)
Il y a déjà beaucoup de réponses, mais toujours aucune des solutions ci-dessus n'avait tout le nécessaire de positionnement sophistiqué requis pour une animation "parfaite" sans bug, rétrocompatible et sans scintillement. (bug lors de l'animation de frame / bounds et contentOffset ensemble, différentes orientations d'interface, clavier split iPad, ...)
Permettez-moi de partager ma solution:
(en supposant que vous avez configuré
UIKeyboardWill(Show|Hide)Notification
)la source
UIApplication.shared.sendAction(...)
. Voici la version Swift 3 de votre réponse (moins la portion willHide), avec l'sendAction
implémentation: gist.github.com/xaphod/7aab1302004f6e933593a11ad8f5a72dShiun a déclaré: "Il s'est avéré que l'UIScrollView amène implicitement l'UITextField actuellement édité dans la fenêtre visible implicitement" Cela semble être vrai pour iOS 3.1.3, mais pas 3.2, 4.0 ou 4.1. J'ai dû ajouter un scrollRectToVisible explicite afin de rendre l'UITextField visible sur iOS> = 3.2.
la source
[UITextField scrollTextFieldToVisibleIfNecessary]
méthode privée qui à son tour appelle[UIScrollView scrollRectToVisible]
quand[UITextField becomeFirstResponder]
est appelé. Voir github.com/leopatras/ios_textfields_on_scrollview . Si les contraintes et les contrôleurs de vue sont correctement configurés, il n'est en fait pas nécessaire d'appelerscrollRectToVisible
explicitement (au moins depuis IOS 11).Une chose à considérer est de savoir si vous souhaitez utiliser un
UITextField
seul. Je n'ai rencontré aucune application iPhone bien conçue qui utilise réellement enUITextFields
dehors deUITableViewCells
.Ce sera un travail supplémentaire, mais je vous recommande d'implémenter toutes les vues d'entrée de données une vue de table. Ajoutez un
UITextView
à votreUITableViewCells
.la source
UITableView
est malheureusement la seule voie à suivre. Les notifications du clavier sont fragiles et ont changé au fil du temps. Exemple de code sur Stack Overflow: stackoverflow.com/a/32390936/218152Ce document détaille une solution à ce problème. Regardez le code source sous «Déplacement de contenu situé sous le clavier». C'est assez simple.
EDIT: Remarqué il y a un petit problème dans l'exemple. Vous voudrez probablement écouter au
UIKeyboardWillHideNotification
lieu deUIKeyboardDidHideNotification
. Sinon, la vue de défilement derrière le clavier sera tronquée pendant la durée de l'animation de fermeture du clavier.la source
Solution la plus simple trouvée
la source
int movement = (up ? -movementDistance : movementDistance);
if (textField.frame.origin.y < self.view.frame.size.height - keyboard.height) { movementDistance = 0 }
Veuillezkeyboard
noter que la variable est le CGRect du clavier qui apparaît que vous obtenez en faisant:let keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey]!.CGRectValue())!
Petit correctif qui fonctionne pour de nombreux UITextFields
la source
rect.origin.y=+currTextField.frame.origin.y
fonctionne bien merciLe code RPDP déplace avec succès le champ de texte hors du chemin du clavier. Mais lorsque vous faites défiler vers le haut après avoir utilisé et fermé le clavier, le haut a été déplacé hors de la vue. Cela est vrai pour le simulateur et l'appareil. Pour lire le contenu en haut de cette vue, il faut recharger la vue.
Son code suivant n'est-il pas censé faire baisser la vue?
la source
Je ne sais pas si le déplacement de la vue vers le haut est la bonne approche, je l'ai fait de manière différente, en redimensionnant l'UIScrollView. Je l'ai expliqué en détail sur un petit article
la source
Pour revenir à l'état d'affichage d'origine, ajoutez:
la source
Essayez cette petite astuce.
la source
Il y a tellement de solutions, mais j'ai passé quelques heures avant que ça marche. Donc, je mets ce code ici (il suffit de coller dans le projet, aucune modification n'est nécessaire):
PS: J'espère que le code aidera quelqu'un à produire rapidement l'effet souhaité. (Xcode 4.5)
la source
@ user271753
Pour rétablir la vue d'origine, ajoutez:
la source
Il ne nécessite pas de vue de défilement pour pouvoir déplacer le cadre de vue. Vous pouvez modifier le cadre d'une
viewcontroller's
vue afin que la vue entière se déplace juste assez pour placer le champ de texte du premier répondant au-dessus du clavier. Lorsque j'ai rencontré ce problème, j'ai créé une sous-classeUIViewController
qui fait cela. Il observe que le clavier apparaîtra une notification et trouve la sous-vue du premier répondant et (si nécessaire) il anime la vue principale vers le haut juste assez pour que le premier répondant soit au-dessus du clavier. Lorsque le clavier se cache, il anime la vue où elle était.Pour utiliser cette sous-classe, faites de votre contrôleur de vue personnalisé une sous-classe de GMKeyboardVC et il hérite de cette fonctionnalité (assurez-vous simplement que vous implémentez
viewWillAppear
etviewWillDisappear
qu'ils doivent appeler super). La classe est sur github .la source
Rapide 4 .
Vous pouvez facilement monter et descendre
UITextField
OuUIView
AvecUIKeyBoard
AvecAnimation
la source
Voici la solution de piratage que j'ai trouvée pour une mise en page spécifique. Cette solution est similaire à la solution de Matt Gallagher en ce qu'elle fait défiler une section en vue. Je suis encore nouveau dans le développement d'iPhone et je ne connais pas le fonctionnement des mises en page. Ainsi, ce hack.
Mon implémentation devait prendre en charge le défilement lorsque vous cliquez dans un champ, ainsi que le défilement lorsque l'utilisateur sélectionne ensuite sur le clavier.
J'avais une UIView d'une hauteur de 775. Les commandes sont réparties essentiellement en groupes de 3 sur un grand espace. Je me suis retrouvé avec la disposition IB suivante.
Voici le hack
J'ai défini la hauteur UIScrollView à 500 unités plus grande que la disposition réelle (1250). J'ai ensuite créé un tableau avec les positions absolues dans lesquelles je dois faire défiler et une fonction simple pour les obtenir en fonction du numéro d'étiquette IB.
Maintenant, tout ce que vous avez à faire est d'utiliser les deux lignes de code suivantes dans textFieldDidBeginEditing et textFieldShouldReturn (cette dernière si vous créez une navigation de champ suivante)
Un exemple.
Cette méthode ne fait pas «défiler vers l'arrière» comme le font d'autres méthodes. Ce n'était pas une exigence. Encore une fois, c'était pour une UIView assez «haute», et je n'ai pas eu de jours pour apprendre les moteurs de disposition internes.
la source
Selon les documents , à partir d'iOS 3.0, la
UITableViewController
classe redimensionne et repositionne automatiquement sa vue de table lorsqu'il y a une modification en ligne des champs de texte. Je pense qu'il ne suffit pas de mettre le champ de texte à l'intérieur d'unUITableViewCell
comme certains l'ont indiqué.De la documentation :
la source
Vous devez simplement copier-coller ci-dessous l'exemple de code et modifier votre champ de texte ou toute vue que vous souhaitez déplacer vers le haut.
Étape 1
Étape 2
Étape 3
Référence : eh bien, merci d'apprécier ce gars , qui a partagé cette belle coupure de code, une solution propre.
J'espère que ce serait sûrement utile à quelqu'un là-bas.
la source
Vous cherchez un bon tutoriel pour les débutants sur le sujet, j'ai trouvé le meilleur tutoriel ici .
Dans l'
MIScrollView.h
exemple au bas du didacticiel, assurez-vous de mettre un espace àcomme tu vois.
la source
Quand
UITextField
est dans unUITableViewCell
défilement doit être configuré automatiquement.Si ce n'est pas le cas, c'est probablement à cause d'un code / d'une configuration incorrecte de la table.
Par exemple, lorsque j'ai rechargé ma longue table avec une
UITextField
en bas comme suit,puis mon champ de texte en bas a été obscurci par le clavier qui est apparu lorsque j'ai cliqué à l'intérieur du champ de texte.
Pour résoudre ce problème, je devais le faire -
la source
viewWillAppear
n'est pas appelé. EtreloadData
ne rend pas visibles les lignes obscurcies.Utilisez ce tiers, vous n'avez pas besoin d'écrire une seule ligne
https://github.com/hackiftekhar/IQKeyboardManager
téléchargez le projet et glissez-déposez
IQKeyboardManager
votre projet. Si vous trouvez un problème, veuillez lire leREADME
document.Les gars enlèvent vraiment son mal de tête pour gérer le clavier.
la source
Remarque : cette réponse suppose que votre textField est dans un scrollView.
Je préfère traiter cela en utilisant scrollContentInset et scrollContentOffset au lieu de jouer avec les cadres de ma vue.
Écoutons d'abord les notifications du clavier
L'étape suivante consiste à conserver une propriété qui représente le premier répondeur actuel (UITextfield / UITextVIew qui possède actuellement le clavier).
Nous utilisons les méthodes déléguées pour définir cette propriété. Si vous utilisez un autre composant, vous aurez besoin de quelque chose de similaire.
Notez que pour textfield, nous le définissons dans didBeginEditing et pour textView dans shouldBeginEditing. C'est parce que textViewDidBeginEditing est appelé après UIKeyboardWillShowNotification pour une raison quelconque.
Enfin, voici la magie
la source
Ceci est la solution utilisant Swift.
la source