Après beaucoup d'essais et d'erreurs, j'abandonne et pose la question. J'ai vu beaucoup de gens avec des problèmes similaires, mais je ne peux pas obtenir toutes les réponses pour bien travailler.
J'en ai un UITableView
qui est composé de cellules personnalisées. Les cellules sont constituées de 5 champs de texte côte à côte (un peu comme une grille).
Lorsque j'essaie de faire défiler et de modifier les cellules en bas de la UITableView
, je n'arrive pas à positionner correctement mes cellules au-dessus du clavier.
J'ai vu de nombreuses réponses parler de la modification des tailles de vue, etc ... mais aucune n'a bien fonctionné jusqu'à présent.
Quelqu'un pourrait-il clarifier la "bonne" façon de procéder avec un exemple de code concret?
Réponses:
Si vous utilisez UITableViewController au lieu de UIViewController, il le fera automatiquement.
la source
La fonction qui fait le défilement pourrait être beaucoup plus simple:
C'est tout. Aucun calcul du tout.
la source
contentInset
, ce qui n'est apparemment pas pris en compte lors de la demande devisibleRows
ouindexPathsForVisibleRows
.Je fais quelque chose de très similaire, c'est générique, pas besoin de calculer quelque chose de spécifique pour votre code. Vérifiez simplement les remarques sur le code:
Dans MyUIViewController.h
Dans MyUIViewController.m
Version Swift 1.2+:
la source
[tableView scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionMiddle animated: YES];
MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate]; CGFloat tabBarHeight = appDelegate.tabBarController.tabBar.frame.size.height;
Ensuite, soustrayez tabBarHeight de la hauteur du clavier partout où vous utilisez la hauteur du clavier.La solution la plus simple pour Swift 3 , basée sur la solution de Bartłomiej Semańczyk :
la source
Notification
au lieu deNSNotification
serait plus "Swift 3-y" :-)J'ai eu le même problème mais j'ai remarqué qu'il n'apparaît que dans une seule vue. J'ai donc commencé à chercher les différences dans les contrôleurs.
J'ai découvert que le comportement de défilement est défini dans
- (void)viewWillAppear:(BOOL)animated
la super instance.Assurez-vous donc de mettre en œuvre comme ceci:
Et peu importe si vous utilisez
UIViewController
ouUITableViewController
; vérifié en mettant unUITableView
comme une sous-vue de self.view dans leUIViewController
. C'était le même comportement. La vue ne permettait pas de faire défiler si l'appel[super viewWillAppear:animated];
manquait.la source
J'ai peut-être manqué cela, car je n'ai pas lu l'intégralité du message ici, mais ce que j'ai trouvé semble d'une simplicité trompeuse. Je n'ai pas mis cela à l'épreuve, testant dans toutes les situations, mais il semble que cela devrait fonctionner très bien.
ajustez simplement le contentInset de la table en fonction de la hauteur du clavier, puis faites défiler la cellule vers le bas:
et bien sûr
est-ce trop simple? est-ce que je manque quelque chose? jusqu'à présent ça marche bien pour moi, mais comme je l'ai dit, je ne l'ai pas mis dans l'essoreuse ...
la source
[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]
contentInset
et ne changera pas brusquement les limites du défilement.Je pense que j'ai trouvé la solution pour correspondre au comportement des applications d'Apple.
Tout d'abord, dans votre viewWillAppear: abonnez-vous aux notifications du clavier, afin que vous sachiez quand le clavier s'affichera et se cachera, et le système vous indiquera la taille du clavier, mais n'oubliez pas de vous désinscrire dans votre viewWillDisappear:.
Implémentez les méthodes similaires à celles ci-dessous afin d'ajuster la taille de votre tableView pour qu'elle corresponde à la zone visible une fois que le clavier s'affiche. Ici, je surveille l'état du clavier séparément afin de pouvoir choisir moi-même le moment de remettre la tableView à sa pleine hauteur, car vous recevez ces notifications à chaque changement de champ. N'oubliez pas d'implémenter keyboardWillHide: et choisissez un endroit approprié pour fixer la taille de votre tableView.
Maintenant, voici le bit de défilement, nous travaillons d'abord sur quelques tailles, puis nous voyons où nous en sommes dans la zone visible, et définissons le rect que nous voulons faire défiler pour être soit la demi-vue au-dessus ou en dessous du milieu du champ de texte en fonction où il est dans la vue. Dans ce cas, nous avons un tableau de UITextFields et une énumération qui les garde, donc la multiplication de rowHeight par le numéro de ligne nous donne le décalage réel du cadre dans cette vue extérieure.
Cela semble fonctionner très bien.
la source
UIKeyboardBoundsUserInfoKey
est obsolète depuis iOS 3.2. Voir ma solution ci-dessous qui fonctionne sur toutes les versions iOS actuelles ≥ 3.0. / @ iPhoneDevSi vous pouvez utiliser
UITableViewController
, vous obtenez la fonctionnalité gratuitement. Parfois, cependant, ce n'est pas une option, en particulier si vous avez besoin de plusieurs vues et pas seulement duUITableView
.Certaines des solutions présentées ici ne fonctionnent pas sur iOS ≥4, certaines ne fonctionnent pas sur iPad ou en mode paysage, certaines ne fonctionnent pas pour les claviers Bluetooth (où nous ne voulons pas de défilement), d'autres non fonctionne lors du basculement entre plusieurs champs de texte. Donc, si vous choisissez une solution, assurez-vous de tester ces cas. C'est la solution que nous
utilisonsutilisée dans InAppSettingsKit :Voici le code complet de la classe dans InAppSettingsKit. Pour le tester, utilisez le volet enfant "Liste complète" où vous pouvez tester les scénarios mentionnés ci-dessus.
la source
La solution la plus simple pour Swift :
la source
J'espère que vous avez déjà trouvé une solution en lisant tout cela. Mais j'ai trouvé ma solution comme suit. Je m'attends à ce que vous ayez déjà une cellule avec
UITextField
. Ainsi, lors de la préparation, conservez simplement l'index de ligne dans la balise du champ de texte.Créez une
activeTextField
instance deUITextField
avec une portée globale comme ci-dessous:Donc, maintenant vous venez de copier coller mon code à la fin. Et n'oubliez pas d'ajouter
UITextFieldDelegate
Enregistre le clavier
notifications
Poignées du clavier
Notifications
:Appelé lorsque le
UIKeyboardDidShowNotification
est envoyé.Appelé lorsque le
UIKeyboardWillHideNotification
est envoyéMaintenant, une chose reste, appelez la
registerForKeyboardNotifications
méthode dans laViewDidLoad
méthode comme suit:Vous avez terminé, j'espère que votre
textFields
volonté ne sera plus cachée par le clavier.la source
En combinant et en remplissant les blancs de plusieurs réponses (en particulier Ortwin Gentz, utilisateur 98013) et d'une autre publication, cela fonctionnera par défaut pour le SDK 4.3 sur un iPad en mode Portrait ou Paysage:
la source
Si vous utilisez une vue modifiable pour placer vos champs de texte ( de Jeff Lamarche ), vous pouvez simplement faire défiler la vue de table en utilisant la méthode déléguée comme ceci.
(Remarque: mes champs de texte sont stockés dans un tableau avec le même index que la ligne dans la vue table)
la source
Les notifications au clavier fonctionnent, mais l'exemple de code d'Apple suppose que la vue de défilement est la vue racine de la fenêtre. Ce n'est généralement pas le cas. Vous devez compenser les barres de tabulation, etc., pour obtenir le bon décalage.
C'est plus facile qu'il n'y paraît. Voici le code que j'utilise dans un UITableViewController. Il a deux variables d'instance, hiddenRect et keyboardShown.
la source
UIKeyboardCenterEndUserInfoKey
etUIKeyboardBoundsUserInfoKey
sont obsolètes à partir d'iOS 3.2. Voir ma solution ci-dessous qui fonctionne sur toutes les versions iOS actuelles ≥ 3.0.Si vous utilisez
Three20
, utilisez laautoresizesForKeyboard
propriété. Définissez simplement la-initWithNibName:bundle
méthode de votre contrôleur de vueCela prend en charge:
Fait et fait.
la source
Mon approche:
Je sous-classe d'abord UITextField et j'ajoute une propriété indexPath. Dans la méthode cellFor ... je remets la propriété indexPath.
J'ajoute ensuite le code suivant:
au textFieldShould / WillBegin ... etc.
Lorsque le clavier disparaît, vous devez l'inverser avec:
la source
Une solution plus rationalisée. Il se glisse dans les méthodes déléguées UITextField, donc il ne nécessite pas de messages avec les notifications UIKeyboard.
Notes de mise en œuvre:
kSettingsRowHeight - la hauteur d'un UITableViewCell.
offsetTarget et offsetThreshold sont supprimés de kSettingsRowHeight. Si vous utilisez une hauteur de ligne différente, définissez ces valeurs sur la propriété y du point. [alt: calculer le décalage de ligne d'une manière différente.]
}
}
la source
Utilisez la
UITextField's
delegate
méthode:Rapide
Objectif c
la source
Solution complète Swift 4.2
J'ai créé GIST avec un ensemble de protocoles qui simplifie le travail en ajoutant de l'espace supplémentaire lorsque le clavier est affiché, masqué ou modifié.
Caractéristiques :
Usage
Exemple d'utilisation de base dans le contrôleur de vue qui contient une vue de défilement (la vue de table est également prise en charge bien sûr).
Noyau: le cadre change d'observateur
Le protocole
KeyboardChangeFrameObserver
déclenchera l'événement chaque fois que le cadre du clavier a été modifié (y compris l'affichage, le masquage, le changement de cadre).addKeyboardFrameChangesObserver()
àviewWillAppear()
ou méthode similaire.removeKeyboardFrameChangesObserver()
àviewWillDisappear()
ou méthode similaire.Implémentation: vue défilante
ModifableInsetsOnKeyboardFrameChanges
protocole ajoute laUIScrollView
prise en charge au protocole principal. Il modifie les encarts de la vue de défilement lorsque le cadre du clavier est modifié.Votre classe doit définir la vue de défilement, ses encarts seront augmentés / diminués lors des changements de cadre du clavier.
la source
Puisque vous avez des champs de texte dans un tableau, le meilleur moyen est vraiment de redimensionner le tableau - vous devez définir le tableView.frame pour être plus petit en hauteur par la taille du clavier (je pense autour de 165 pixels), puis le développer à nouveau lorsque le clavier est fermé.
Vous pouvez également également désactiver l'interaction utilisateur pour la tableView à ce moment-là, si vous ne souhaitez pas que l'utilisateur défile.
la source
Cela fonctionne parfaitement, et sur iPad aussi.
la source
J'ai essayé presque la même approche et j'ai trouvé un code plus simple et plus petit pour la même chose. J'ai créé un IBOutlet iTextView et associé à l'UITextView dans l'IB.
la source
Donc, après des heures de travail exténuant à essayer d'utiliser ces solutions actuelles (et qui ont complètement échoué), j'ai finalement fait fonctionner les choses correctement et les ai mises à jour pour utiliser les nouveaux blocs d'animation. Ma réponse est entièrement basée sur la réponse d'Ortwin ci-dessus .
Donc, pour une raison quelconque, le code ci-dessus ne fonctionnait tout simplement pas pour moi. Ma configuration semblait assez similaire aux autres, mais peut-être parce que j'étais sur un iPad ou 4.3 ... aucune idée. Il faisait des calculs farfelus et tirait ma vue de table de l'écran.
Voir le résultat final de ma solution: http://screencast.com/t/hjBCuRrPC (veuillez ignorer la photo. :-P)
Je suis donc allé avec l'essentiel de ce que faisait Ortwin, mais j'ai changé la façon dont il faisait des calculs pour additionner origin.y & size.height de ma vue de table avec la hauteur du clavier. Lorsque je soustrais la hauteur de la fenêtre de ce résultat, cela me dit combien d'intersection j'ai en cours. Si sa valeur est supérieure à 0 (c'est-à-dire qu'il y a un certain chevauchement), j'exécute l'animation de la hauteur du cadre.
De plus, il y a eu quelques problèmes de rafraîchissement qui ont été résolus en 1) attendant de faire défiler jusqu'à la cellule jusqu'à ce que l'animation soit terminée et 2) en utilisant l'option UIViewAnimationOptionBeginFromCurrentState lors du masquage du clavier.
Quelques choses à noter.
Encore une fois, je ne me serais pas approché de cette réponse si je Ortwin n'en avait pas fourni l'essentiel. Voici le code:
la source
Ce soluton fonctionne pour moi, veuillez noter la ligne
Vous pouvez modifier la valeur 160 pour l'adapter à votre travail
la source
Fil de discussion très intéressant, j'ai également fait face au même problème peut être pire parce que
Alors lisez les discussions ici et implémentez ma version, ce qui m'a aidé à remonter mon contenu sur iPad en mode paysage . Voici le code (ce n'est pas indéréglable et tout, mais cela a résolu mon problème).
// MISE EN ŒUVRE POUR GÉRER LE MODE PAYSAGE UNIQUEMENT
// Appelé lorsque la UIKeyboardWillHideNotification est envoyée
-anoop4real
la source
Je viens de résoudre un tel problème par moi-même après avoir référé une masse de solutions trouvées via Google et Stack Overflow.
Tout d'abord, veuillez vous assurer que vous avez configuré une sortie IBO de votre UIScrollView, puis veuillez examiner de près Apple Doc: Gestion des claviers . Enfin, si vous pouvez faire défiler l'arrière-plan, mais que le clavier couvre toujours les champs de texte, jetez un œil à ce morceau de code:
La principale différence entre cette pièce et Apple réside dans la condition if. Je crois que le calcul par Apple de la distance de défilement et de la condition que le champ de texte couvert par le clavier ne soit pas précis, j'ai donc fait ma modification comme ci-dessus.
Dites moi si ca marche
la source
Un exemple dans Swift, en utilisant le point exact du champ de texte de Get indexPath de UITextField dans UITableViewCell avec Swift :
la source
Une autre méthode simple (ne fonctionne qu'avec une seule section)
la source
Si votre UITableView est géré par une sous-classe de UITableViewController et non UITableView, et que le délégué du champ de texte est UITableViewController, il devrait gérer automatiquement tout le défilement - tous ces autres commentaires sont très difficiles à implémenter dans la pratique.
Pour un bon exemple, voir l'exemple de projet de code Apple: TaggedLocations.
Vous pouvez voir qu'il défile automatiquement, mais il ne semble pas y avoir de code qui le fasse. Ce projet a également des cellules de vue de tableau personnalisées, donc si vous construisez votre application avec comme guide, vous devriez obtenir le résultat souhaité.
la source
Voici comment j'ai fait ce travail, qui est un mélange des réponses de Sam Ho et Marcel W, et quelques-unes de mes propres corrections de bugs apportées à mon code merdique. J'utilisais un UITableViewController. Le tableau se redimensionne désormais correctement lorsque le clavier est affiché.
1) Dans
viewDidLoad
j'ai ajouté:self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
2) J'avais oublié d'appeler les
super
équivalents enviewWillAppear
etawakeFromNib
. Je les ai rajoutés.la source
UITableViewController
fait le défilement automatiquement, en effet. La différence par rapport à l'utilisation d'unUIViewController
est que vous devez créer des éléments Navbar-Buttonitems par programme en utilisant leNavigationController
, lorsque vous utilisez unTableViewController
.la source