Je construis une conversation. Tout semble être assez correct mais je me suis heurté à une sorte de problème 'buggy'.
j'ai eu UIViewController avec une barre UITextView pour entrer un message et UITableView. Ils sont dans cette contrainte: "V:|-(64)-[chatTable][sendMessageBar]-(keyboard)-|"
. Lorsque le clavier n'est pas éteint, la constante de cette contrainte est 0
. et après la sortie du clavier - j'augmente la constante à la hauteur du clavier.
quand le clavier n'est pas sorti:
self.table.contentSize = (375.0,78.5)
self.table.bounds = (0.0,-490.0,375.0,568.5)
self.table.frame = (0.0,64.0,375.0,568.5)
self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,0.0,375.0,568.5)
self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,0.0,375.0,568.5)
et quand le clavier sort:
self.table.contentSize = (375.0,78.5)
self.table.bounds = (0.0,-274.0,375.0,352.5
self.table.frame = (0.0,64.0,375.0,352.5)
self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,-137.5,375.0,137.5)
self.table.subviews[0].frame (UITableViewWrapperView) = (0.0,0.0,375.0,137.5)
Ainsi, UITableViewWrapperView, après avoir augmenté la constante de contrainte, diffère en taille de sa superview - UITableView. Y'a t'il un moyen d'arranger cela ? Je suppose que UITableViewWrapperView
changerait son cadre et ses limites en fonction de UITableView
mais ce n'est pas le cas.
Des idées où est le problème ou comment pourrais-je le contourner?
AJOUTER:
Après quelques recherches supplémentaires, il semble que cela se produise quelque part entre viewWillLayoutSubviews
et viewDidLayoutSubviews
. C'est un peu bizarre
override func viewWillLayoutSubviews() {
println("WrapperView Frame :991: \(self.table.subviews[0].frame)") \\ WrapperView Frame :991: (0.0,0.0,375.0,568.5)
super.viewWillLayoutSubviews()
println("WrapperView Frame :992: \(self.table.subviews[0].frame)") \\ WrapperView Frame :992: (0.0,0.0,375.0,568.5)
}
override func viewDidLayoutSubviews() {
println("WrapperView Frame :6: \(self.table.subviews[0].frame)") \\ WrapperView Frame :6: (0.0,-137.5,375.0,137.5)
super.viewDidLayoutSubviews()
println(">> viewDidLayoutSubviews")
}
Il semble donc que quelque chose se passe là-bas qui dérange la UITableViewWrapperView
Ce qui suit l'a corrigé pour moi:
func fixTableViewInsets() {
let zContentInsets = UIEdgeInsetsZero
tableView.contentInset = zContentInsets
tableView.scrollIndicatorInsets = zContentInsets
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
fixTableViewInsets()
}
J'ai découvert qu'à viewWillAppear (), les incrustations étaient toutes égales à 0. Mais à viewDidAppear (), elles avaient été modifiées pour être apparemment décalées pour la barre de navigation, etc. Cela rend UITableViewWrapperView différent de UITableView. J'ai changé les encarts dans sa propre routine afin qu'il soit plus facile d'expérimenter avec l'appel de différents endroits. ViewWillLayoutSubviews () le laissa être changé avant d'être présenté. Placer le changement dans viewDidAppear () provoqua le jerk de la table.
Je me suis heurté à cela aujourd'hui et, bien que le correctif suggéré par @anorskdev fonctionne correctement, il semble que la cause première du problème soit la propriété automaticallyAdjustsScrollViewInsets
de UIViewController, qui est true
par défaut. Je l'ai éteint dans mon story-board et le problème a disparu. Recherchez la case à cocher "Ajuster les encarts de vue de défilement" dans l'inspecteur du contrôleur de vue et assurez-vous qu'elle est décochée.
Il semble que ce soit un bogue (lutter avec ce bogue a pris toute la journée pour moi) Enfin ça la solution de contournement a aidé:
for (UIView *subview in tableView.subviews)
{
if ([NSStringFromClass([subview class]) isEqualToString:@"UITableViewWrapperView"])
{
subview.frame = CGRectMake(0, 0, tableView.bounds.size.width, tableView.bounds.size.height);
}
}
Dans iOS 11, UITableViewWrapperView
est parti, ce problème ne peut donc se produire que sur les versions iOS ultérieures. Je l'ai fait face sur iOS10 lorsque j'ai poussé la variable UIViewController
personnalisée dans la pile UINavigationController
.
La solution consiste donc à remplacer la propriété automaticallyAdjustsScrollViewInsets
dans le contrôleur de vue personnalisé comme ceci:
override var automaticallyAdjustsScrollViewInsets: Bool {
get {
return false
}
set {
}
}
Je faisais face au même problème sur tvOS 11.3, et aucune des suggestions liées à zéro encart ou désactivation du défilement n'a fait le travail, sauf en boucle dans les sous-vues de tableView et en définissant le cadre UITableViewWrapperView avec le cadre de tableView.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
for view in tableView.subviews {
if String(describing: type(of: view)) == "UITableViewWrapperView" {
view.frame = CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: tableView.bounds.size.height)
}
}
}
Après une petite recherche, j'ai trouvé cette solution en réglant toutes les safeAreaInsets
et layoutMargins
sur UITableView
à zéro:
Swift 4 Snipset:
class CustomTableView: UITableView {
override var safeAreaInsets: UIEdgeInsets {
get {
return .zero
}
}
override var layoutMargins: UIEdgeInsets {
get {
return .zero
}
set {
super.layoutMargins = .zero
}
}
}
Le problème principal est safeAreaInsets introduit dans tvOS 11.0
- la UITableViewWrapperView
vient de récupérer les propriétés de la vue parent (UITableView) et affiche le contenu avec safeAreaInsets.