J'ai beaucoup lu sur la transition de l'interface utilisateur iOS7.
Je ne peux pas obtenir ce que ces trois propriétés automaticallyAdjustsScrollViewInsets
, extendedLayoutIncludesOpaqueBars
, edgesForExtendedLayout
??
Par exemple, j'essaie de faire en sorte que mes contrôleurs de vue démarrent en dessous de la barre d'état, mais je ne parviens pas à l'obtenir.
À partir de iOS7, les contrôleurs de vue utilisent la disposition en plein écran par défaut. En même temps, vous avez plus de contrôle sur la façon dont il affiche ses vues, et cela se fait avec ces propriétés:
edgeForExtendedLayout
En gros, avec cette propriété, vous définissez quels côtés de votre vue peuvent être étendus pour couvrir tout l'écran. Imaginez que vous poussez un UIViewController
dans un UINavigationController
. Lorsque la vue de ce contrôleur de vue est affichée, elle commence à l'endroit où se termine la barre de navigation, mais cette propriété définit les côtés de la vue (haut, gauche, bas, droite) pouvant être étendus pour remplir tout l'écran.
Voyons le 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
; par conséquent, la valeur par défaut est prise (UIRectEdgeAll
), de sorte que la vue étend sa disposition pour remplir tout l'écran.
Voici le résultat:
Comme vous pouvez le constater, l'arrière-plan rouge s'étend derrière la barre de navigation et la barre d'état.
Maintenant, vous allez définir cette valeur sur UIRectEdgeNone
, de sorte que vous indiquez au contrôleur de vue de ne pas étendre la vue pour 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:
automatiquementAdjustsScrollViewInsets
Cette propriété est utilisée lorsque votre vue est une UIScrollView
ou similaire, comme une UITableView
. Vous voulez que votre tableau commence à l'endroit où se termine la barre de navigation, car vous ne verrez pas tout le contenu sinon, mais vous voulez aussi que votre tableau couvre tout l'écran lors du défilement. Dans ce cas, la définition de edgesForExtendedLayout
sur Aucune ne fonctionnera pas, car votre tableau commencera à faire défiler l'emplacement de la barre de navigation à la fin et ne suivra pas.
C’est ici que cette propriété est utile, si vous laissez le contrôleur de vue ajuster automatiquement les incrustations (définissez cette propriété sur OUI, ainsi que sur la valeur par défaut), des incrustations seront ajoutées au haut de la table. la barre se termine, mais le défilement couvrira tout l'écran.
C'est quand est réglé sur NO:
Et OUI (par défaut):
Dans les deux cas, le tableau défile derrière la barre de navigation, mais dans le second cas (OUI), il commencera par le dessous de la barre de navigation.
extendedLayoutIncludesOpaqueBars
Cette valeur est juste un ajout aux précédents. Par défaut, ce paramètre est défini sur NO. Si 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 sur YES, la vue sera à nouveau visible sous la barre d'état.
Si quelque chose n'est pas clair, écrivez un commentaire et je vais y répondre.
Comment iOS sait-il ce que UIScrollView doit utiliser?
iOS saisit la première sous-vue de la vue de votre ViewController, celle de l'index 0, et s'il s'agit d'une sous-classe de UIScrollView
, elle lui applique les propriétés expliquées.
Bien entendu, cela signifie que UITableViewController
fonctionne par défaut (puisque UITableView
est la première vue).
Vous ne savez pas si vous utilisez des storyboards, mais si c'est le cas, pour que vos contrôleurs de vue démarrent en dessous de la barre d'état (et au-dessus de la barre du bas):
Sélectionnez le contrôleur de vue dans IB. Dans l'inspecteur d'attributs, désélectionnez "Étendre les bords - Barres inférieures" et "Étendre les bords - Barres inférieures".
J'utilise des storyboards et les conseils ci-dessus ont fonctionné, mais je ne savais pas exactement comment le mettre en œuvre. Vous trouverez ci-dessous un bref exemple dans Swift montrant comment le problème a été résolu en mettant la solution recommandée dans 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: le réglage automatique est défini sur true par défaut, ce qui crée une différence entre la conception du storyboard et le simulateur.
Résolu: Code ci-dessus appliqué, désactivant le réglage automatique.
J'ai résolu ce problème en ajoutant cette ligne, mais mon problème était lié à un UIView
, pas UIScrollView
self.navigationController.navigationBar.translucent = NO;
N'oubliez pas que la propriété automaticallyAdjustsScrollViewInsets
ne fonctionne que si une vue de défilement (vue de table, vue de collection, ...) est soit
D'autres ont suggéré que cela fonctionne, même s'il s'agit de la première sous-vue, mais il existe d'autres vues de défilement dans la hiérarchie des vues.
EDIT (extension bricolage)
Si vous souhaitez un comportement similaire même si vous ne pouvez pas remplir ces conditions (par exemple, vous avez une image d'arrière-plan sous la vue de défilement), vous pouvez régler les encarts de la vue de défilement manuellement. Mais s'il vous plaît, ne réglez pas cette valeur comme 44 ou 64 ou même 20, comme beaucoup le suggèrent autour de SO. Vous ne pouvez pas connaître la taille jamais. Il peut y avoir la notification d'incall/gps/audio, la barre de navigation ne doit pas toujours être 44 pts etc.
Je pense que la meilleure solution consiste à utiliser layoutGuide length
dans 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 bottomLayoutGuide de la même manière.