IOS7: décalage UIScrollView dans UINavigationController

126

Je migre actuellement mon application sur iOS 7 et je suis bloqué depuis des heures sur le nouveau contrôleur de navigation / gestion de la barre.

Avant, lorsque nous avions un contrôleur de navigation, nous avions un extrait comme celui-ci:

UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:[[MainViewController alloc]init]];

Dans l'interface builder, nous avons eu le choix de définir une barre de navigation existante pour la vue et tout correspond au contenu de la vue réelle.

OK donc maintenant, je n'ai aucune idée de comment concevoir correctement avec le constructeur d'interface. J'ai toujours mon extrait de code pour initialiser mon navcontroller. Cependant, dans le générateur d'interface de mon MainViewController, si je définis une barre d'état sur une barre de navigation translucide ou opaque, j'ai un décalage de 44px en haut (voir ci-dessous).


Interface Builder _________________________Et le résultat


Maintenant, si je règle la barre d'état sur aucun, il n'y a pas de décalage en haut, mais comme la vue sur le simulateur est plus petite à cause de la barre de navigation, le bas de la vue dans le générateur d'interface est coupé.

Interface Builder _________________________Et le résultat

Je suppose qu'il me manque vraiment quelque chose ici, mais je ne trouve aucun sujet ou info Apple dans le guide des transitions iOS7 à ce sujet.

Merci de votre aide


ÉDITER

Comme nous pouvons le voir sur les images, le premier enfant de la vue est un UIScrollView qui contient les deux étiquettes, le problème n'apparaît pas lorsqu'il n'y a pas de scrollview. Il apparaît également s'il s'agit d'un UITableView. Si une étiquette est en dehors de UIScrollView, il n'y a pas de décalage par rapport à cette étiquette.

streem
la source
Vous voudrez peut-être utiliser la mise en page automatique si vous ne l'êtes pas, vous pouvez donc vous assurer que certaines vues sont à une distance définie du haut / bas / côté de l'écran
erdekhayser
Je n'utilise en effet pas Autolayout, mais l'utiliser (cocher la case) ne résout pas le problème.
streem
Avec Autolayout, vous devez définir des contraintes pour que les vues restent en place. Xcode ne sait pas ce que vous voulez automatiquement.
erdekhayser le
En voyant votre précédente modification, je viens de découvrir votre problème. Malheureusement, ce n’est pas la solution la plus évidente. Plutôt que d'essayer de tout expliquer à nouveau, j'ai utilisé cette vidéo sur Youtube pour apprendre à configurer des vues de défilement. youtube.com/watch?v=PgeNPRBrB18&feature=youtu.be Bonne chance. Il m'a fallu quelques fois pour le regarder pour bien comprendre ce qu'il faisait.
erdekhayser

Réponses:

286

OK donc j'ai trouvé la solution, j'ai défini dans mon contrôleur la propriété:

self.automaticallyAdjustsScrollViewInsets = false

Cependant, je ne comprends pas vraiment le véritable avantage de cette propriété (ou pourquoi la valeur par défaut est true)

La seule documentation que j'ai trouvée était là:

Mettre à jour

Dans iOS 11 automaticallyAdjustsScrollViewInsetsest obsolète

Vous devez maintenant utiliser:

self.tableView.contentInsetAdjustmentBehavior = .never

Je vous encourage également à vérifier cette question et sa réponse pour mieux comprendre ces propriétés

streem
la source
12
Super trouvaille. UIScrollView dans le storyboard est vraiment compliqué. Je souhaite qu'Apple le rende un peu transparent dans les futures versions de Xcode.
p0lAris
4
Ce code empêche mon UIScrollViewde défiler. Mais sans cela, je ne peux pas me débarrasser du décalage. Weired ...
scaryguy
9
Cet indicateur peut également être désactivé dans votre storyboard / nib, le contrôleur de vue a une case à cocher "Ajuster les encarts de vue de défilement". Cela fait si longtemps que je me cogne la tête contre un mur en essayant de résoudre mes problèmes avec les vues de défilement et la mise en page automatique, encore compliqués par la prise en charge d'iOS 6 et 7. Merci beaucoup d'avoir enfin fourni une solution!
Newtz
2
Le document d'application vous dirait que la configuration de navigationbar.translucent = YES empêcherait la barre de navigation de pousser le contenu vers le bas. C'est le plus gros mensonge et cela m'a coûté de nombreuses heures de travail jusqu'à ce poste. De plus, vous devez définir self.automaticallyAdjustsScrollViewInsets = NO; Merci beaucoup pour ce post !!!!!!! Pomme et pomme?
user779764
J'ai trouvé que cela provoquait un décalage des limites de mon UIScrollView de la hauteur de la barre de navigation (-64 points). J'ai écrasé manuellement ceci à 0, mais j'ai trouvé que UISrollView défilerait toujours dans l'axe des y et «s'alignerait» sur une ligne imaginaire à -64. Votre solution a résolu ce problème.
gdbj
92

La réponse de @ Justafinger a également fonctionné comme un charme pour moi.

Je voulais juste ajouter que ce paramètre peut également être ajusté facilement à partir du constructeur d'interface.

  1. Sélectionnez votre contrôleur de vue
  2. Cliquez sur l'onglet "Inspecteur d'attributs"
  3. Décochez 'Ajuster les inserts de vue de défilement'
  4. Prendre plaisir!

entrez la description de l'image ici

Myxtic
la source
J'ai passé des années à chercher cette option dans les propriétés UIScrollView et non dans le contrôleur de vue! Merci!
Dominic Williams
11

Je rencontrais le même problème, mais j'ai trouvé une propriété plutôt étrange sur le ViewController dans le générateur d'interface qui semble avoir causé cela pour moi. Il existe un ensemble de cases à cocher "Prolonger les bords". J'ai supprimé la vérification "Sous les barres supérieures" et tout a commencé à s'organiser correctement pour moi.

Ben Nicholas
la source
Ouais, celui-ci a mieux fonctionné pour moi que "Ajuster les inserts de vue de défilement"
Dmytro
2

Avec automaticAdjustsScrollViewInsets défini sur YES (le paramètre par défaut), il existe une discordance dans le positionnement de la vue de défilement entre ios6 et ios7, vous devez donc désactiver ce paramètre pour les rendre cohérents. Cependant, ios6 plantera s'il tombe automatiquementAdjustsScrollViewInsets, vous devez donc soit effectuer un changement programmatique de automaticAdjustsScrollViewInsets conditionnel sur ios7, soit désactiver l'option à l'aide du storyboard / NIB

Dawid
la source
2

J'ai eu un problème similaire, après avoir rejeté un viewController, le contentOffset de ma tableView a été changé en (0, -64).

ma solution était un peu bizarre, j'ai essayé toutes les autres réponses mais sans succès, la seule chose qui a résolu mon problème était de changer la position tableView dans l'arborescence des contrôles du .xib

c'était le premier contrôle dans la vue parent comme ceci:

avant

J'ai déplacé la tableView juste après ImageView et cela a fonctionné:

après

il semble que le fait de placer la vue de la table en première position était à l'origine du problème et de déplacer la vue de la table vers une autre position a résolu le problème.

PD Je n'utilise pas autoLayout ni storyboards

j'espère que cela peut aider quelqu'un!

Chuy47
la source
J'ai remarqué ce comportement étrange, je pense que la logique derrière est que les scrollViewInsets sont automatiquement ajustés lorsqu'un scrollview est le premier enfant. Sinon, cela n'a pas vraiment de sens car votre scrollview n'est probablement pas en plein écran.
streem
1

Je suis également confronté à ce problème.

UIScrollView la taille du contenu est calculée par le système d'exploitation comme les autres tailles, les origines fournies par le système de contraintes - c'est pourquoi le système d'exploitation est douteux.

Comment réparer - Vous devez définir explicitement la taille du contenu de UIScrollView:

  1. Incorporer le contenu déroulant dans UIView(je le renomme en ContentView)
  2. Ajouter des contraintes:

ContentView.Weight = View.Weight et ContentView.Height = View.Height

entrez la description de l'image ici

Maslovsa
la source
0

Il semble qu'une solution de contournement consiste à afficher le fichier de storyboard en tant que "iOS 6.1 et versions antérieures" (sélectionnez le fichier de storyboard-> Inspecteur de fichiers-> Document du générateur d'interface-> Afficher sous. Le positionnement des sous-vues dans ce mode montre le décalage.

swhitman
la source
Eh bien, je n'utilise pas de storyboard. Cependant, je ne suis pas sûr que ce soit un problème ios6 à ios7, l'exemple ci-dessus a été entièrement créé avec iOS 7. De plus, j'ai édité ma question, elle n'apparaît (pour autant que je sache) avec uiscrollview et uitableview.
streem
Hmm intéressant ... En regardant cela, vous pouvez ajouter variant = "6xAndEarlier" en haut du XIB dans l'élément de document, car c'est la différence lors du retournement du bit que j'ai mentionné ci-dessus. Et pour info, ce problème se produit également pour uiwebview pour moi.
swhitman
0

Merci les gars pour les solutions! J'ai lutté pendant des heures pour essayer de résoudre le problème. Tout allait bien quand il n'y avait pas de barre de navigation impliquée, mais cela s'est détraqué au moment où j'ai intégré le ViewController dans un NavigationController.

Je l'ai résolu en décochant les encarts Ajuster la vue de défilement et les barres inférieures . Les deux se trouvent dans l'inspecteur d'attributs de ViewController. Mille mercis!

Jackson Gan
la source