Expliquer la différence entre automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout dans iOS7
j'ai beaucoup lu sur la transition iOS7 UI.
Je ne suis pas en mesure d'obtenir ce que ces trois propriétés automaticallyAdjustsScrollViewInsets
, extendedLayoutIncludesOpaqueBars
, edgesForExtendedLayout
??
par exemple, j'essaie de faire démarrer mes contrôleurs de vue en dessous de la barre d'état, mais je ne suis pas en mesure de l'atteindre.
5 réponses
à partir de iOS7, les contrôleurs de vue utilisent par défaut layout plein écran. En même temps, vous avez plus de contrôle sur la façon dont il expose ses vues, et c'est fait avec ces propriétés:
edgesForExtendedLayout
en gros, avec cette propriété vous définissez quels côtés de votre vue peuvent être étendus pour couvrir l'écran entier. Imaginez que vous poussiez un UIViewController
dans un UINavigationController
. Quand la vue de ce le contrôleur de vue est disposé, il commencera là où la barre de navigation se termine, mais cette propriété définira quels côtés de la vue (haut, gauche, bas, droite) peuvent être étendus pour remplir l'écran entier.
voyons cela avec un exemple:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
ici vous ne définissez pas la valeur de edgesForExtendedLayout
, donc la valeur par défaut est prise ( UIRectEdgeAll
), donc la vue étend sa disposition pour remplir l'écran entier.
C'est le résultat:
Comme vous pouvez le voir, le fond rouge s'étend derrière la barre de navigation et la barre d'état.
Maintenant, vous allez définir cette valeur à UIRectEdgeNone
, si vous dites la-vue-contrôleur de ne pas étendre la vue de couvrir l'écran:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
viewController.edgesForExtendedLayout = UIRectEdgeNone;
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
et le résultat:
automaticallyAdjustsScrollViewInsets
cette propriété est utilisée lorsque votre vue est une UIScrollView
ou similaire, comme un UITableView
. Vous voulez que votre table commence là où la barre de navigation se termine, parce que vous ne verrez pas le contenu entier si ce n'est pas le cas, mais en même temps vous voulez que votre table couvre tout l'écran lors du défilement. Dans ce cas, paramétrer edgesForExtendedLayout
à None ne fonctionnera pas car votre table commencera à défiler où le la barre de navigation se termine et ne va pas derrière.
voici où cette propriété est utile, si vous laissez le contrôleur de vue ajuster automatiquement les insets (en définissant cette propriété à Oui, aussi la valeur par défaut) il va ajouter insets au haut de la table, de sorte que la table commencera là où la barre de navigation se termine, mais le rouleau couvrira l'écran entier.
c'est quand est réglé à NO:
et oui (par défaut):
dans les deux cas, la table défile derrière la barre de navigation, mais dans le second cas (oui), elle commencera par dessous la barre de navigation.
extendedLayoutIncludesOpaqueBars
cette valeur n'est qu'un ajout aux précédentes. Par défaut, ce paramètre est défini sur AUCUN. Si l' la barre d'état est opaque, les vues ne seront pas étendues pour inclure la barre d'état, même si vous étendez votre vue pour la couvrir ( edgesForExtendedLayout
à UIRectEdgeAll
).
si vous définissez la valeur à Oui, cela permettra à la vue de passer sous la barre d'État à nouveau.
si quelque chose n'est pas clair, écrivez un commentaire et j'y répondrai.
comment iOS sait-il ce Qu'UIScrollView doit utiliser?
iOS saisit le premier subview dans la vue de votre ViewController, celui de l'index 0, et si c'est une sous-classe de UIScrollView
, alors il applique les propriétés expliquées.
bien sûr, cela signifie que UITableViewController
fonctionne par défaut (puisque le UITableView
est la première vue).
pas sûr si vous utilisez des storyboards, mais si vous l'êtes, pour faire démarrer vos contrôleurs de vue sous la barre d'état (et au-dessus de la barre du bas):
sélectionnez le contrôleur de vue en IB, Dans l'attribut inspector, désélectionnez "Extend Edges-Under Top Bars" et "Extend Edges - Under Bottom Bars".
j'utilise des storyboards et les conseils ci-dessus ont fonctionné mais je ne savais pas exactement comment les mettre en œuvre. Voici un bref exemple dans swift de la façon dont il a résolu le problème en mettant la solution recommandée dans le ViewController.
import Foundation
import UIKit
// This ViewController is connected to a view on a storyboard that
// has a scrolling sub view.
class TheViewController: UIViewController {
// Prepares the view prior to loading. Putting it in viewDidAppear didn't work.
override func viewWillAppear(animated: Bool) {
// this method is an extension of the UIViewController
// so using self works as you might expect.
self.automaticallyAdjustsScrollViewInsets = false
// Default is "true" so this sets it to false tells it to use
// the storyboard as you have it placed
// and not how it thinks it should place it.
}
}
Mon Problème: Ajustement automatique de true par défaut, ce qui fait une différence entre la conception du scénario-maquette et celle du simulateur
résolu: Code ci-dessus appliqué, désactivation l'auto-ajustement.
j'ai résolu ce problème en ajoutant cette ligne, mais mon problème était lié à une UIView
, pas UIScrollView
self.navigationController.navigationBar.translucent = NO;
Juste garder à l'esprit qu'
automaticallyAdjustsScrollViewInsets
la propriété ne fonctionne que si une sorte de défilement (vue de la table, vue de la collection,...) est soit
- Le point de vue de la VC, ou
- Premier sous-vue de ce point de vue
" D'autres ont suggéré que cela fonctionne même si c'est la première sous-vue, mais il y a d'autres vues de défilement dans la hiérarchie de la vue.
MODIFIER (extension de BRICOLAGE)
si vous voulez un comportement similaire même si vous ne pouvez pas remplir ces conditions (par exemple, vous avez une image de fond au-dessous de la vue scroll), vous pouvez ajuster les insets de la vue scroll manuellement. Mais s'il vous plaît ne mettez pas à constante comme 44 ou 64 ou même 20 comme beaucoup le suggèrent autour de SO. Tu ne peux pas connaître la taille. Il peut y avoir la notification incall/gps/audio, la barre de navigation n'a pas à être toujours 44 pts etc.
je pense que la meilleure solution est d'utiliser layoutGuide length
didLayoutSubviews:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
scrollView.scrollIndicatorInsets = scrollView.contentInset
}
vous pouvez utiliser le bottomLayoutGuide de la même manière.