Je transite mon projet vers iOS7. Je suis confronté à un étrange problème lié à la barre de navigation translucide.
J'ai un contrôleur de vue et il a une vue de table comme sous-vue (appelons-le ControllerA). J'initie un nouveau uinavigationcontroller avec le controllerA et le présente de façon modale en utilisant presentviewcontroller. La vue de table du contrôleur de vue présentée est bloquée par la barre de navigation. J'ai défini automaticallyAdjustsScrollViewInsets sur OUI mais le résultat n'a pas changé. Je savais que je peux définir edgeForExtendedLayout sur IRectEdgeNone, mais cela ne rendra pas la barre de navigation plus translucide.
Après cela, j'ai essayé de créer un nouveau contrôleur de vue pour les tests. Il contient presque les mêmes éléments. Mais le résultat est très différent. Le contenu de la vue tabulaire n'est pas bloqué.
Conclusion
J'ai trouvé la réponse sur Apple. Il existe deux cas différents.
Le premier, le contrôleur de vue ajouté est un UITableViewController. Et le problème ne devrait pas apparaître puisque Apple sera automatiquement le rembourrage.
Le second, le contrôleur de vue n'est PAS un UITableViewController. Et dans la hiérarchie des vues, il contient un UITableView. Dans ce cas, si UITableview (ou ScrollView) est la vue principale de viewController ou la première sous-vue de la vue principale, cela fonctionnera. Sinon, le contrôleur de vue ne sait pas quelle vue de défilement au remplissage et il se produira le problème.
Dans mon cas, le contrôleur de vue est le deuxième. Et il y a une vue d'image d'arrière-plan comme première sous-vue de la vue principale. Donc, ça échoue.
Voici le Apple lien du forum des développeurs (besoin d'un compte développeur pour y accéder): https://devforums.Apple.com/message/900138#900138
Si vous souhaitez que la vue sous-chevauche la barre de navigation, mais également qu'elle soit positionnée de manière à ce que le haut du contenu de la vue de défilement soit positionné sous la barre de navigation par défaut, vous pouvez ajouter manuellement un encart supérieur une fois la vue présentée. C'est essentiellement ce que fait le système de disposition des vues lorsque la vue de niveau supérieur est une vue de défilement.
-(void)viewDidLayoutSubviews {
if ([self respondsToSelector:@selector(topLayoutGuide)]) {
UIEdgeInsets currentInsets = self.scrollView.contentInset;
self.scrollView.contentInset = (UIEdgeInsets){
.top = self.topLayoutGuide.length,
.bottom = currentInsets.bottom,
.left = currentInsets.left,
.right = currentInsets.right
};
}
}
Sur la base de la réponse de Tony, j'ai pu contourner ce problème par programme en envoyant temporairement la vue de table à l'arrière, laissez les ajustements être effectués, puis renvoyez la vue d'arrière-plan à l'arrière. Dans mon cas, cette approche ne vacille pas.
Dans le contrôleur de vue:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self.view sendSubviewToBack:self.tableView];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self.view sendSubviewToBack:self.backgroundView];
}
Évidemment, s'il existe d'autres sous-vues sur self.view
vous devrez peut-être les réorganiser également.
Il y a probablement déjà trop de réponses à ce sujet, mais j'ai dû prendre la solution de Christopher et la modifier légèrement pour prendre en charge le redimensionnement de la vue et permettant la modification de l'encart de contenu dans une sous-classe de UIViewController
.
@interface MyViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (assign, nonatomic) UIEdgeInsets scrollViewInitialContentInset;
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setScrollViewInitialContentInset:UIEdgeInsetsZero];
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
if (UIEdgeInsetsEqualToEdgeInsets([self scrollViewInitialContentInset], UIEdgeInsetsZero)) {
[self setScrollViewInitialContentInset:[self.scrollView contentInset]];
}
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
UIEdgeInsets scrollViewInset = [self scrollViewInitialContentInset];
if (UIEdgeInsetsEqualToEdgeInsets(scrollViewInset, UIEdgeInsetsZero) {
if ([self respondsToSelector:@selector(topLayoutGuide)]) {
scrollViewInset.top = [self.topLayoutGuide length];
}
if ([self respondsToSelector:@selector(bottomLayoutGuide)]) {
scrollViewInset.bottom = [self.bottomLayoutGuide length];
}
[self.scrollView setContentInset:scrollViewInset];
}
}
@end
Pour expliquer le point:
Toute sous-classe de MyViewController
peut maintenant modifier le contentInset
de scrollView
dans viewDidLoad
et elle sera respectée. Cependant, si le contentInset
de scrollView
est UIEdgeInsetsZero
: il sera étendu à topLayoutGuide
et bottomLayoutGuide
.
@Christopher Pickslay solution dans Swift 2:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let topInset = topLayoutGuide.length
inTableView.contentInset.top = topInset
inTableView.contentOffset.y = -topInset
inTableView.scrollIndicatorInsets.top = topInset
}
Ouais - un peu ennuyeux.
J'ai une plume avec une seule vue de table dans la vue principale, sans utiliser la mise en page automatique. Il y a une barre d'onglets, une barre de navigation et une barre d'état et l'application doit revenir à 5.0. Dans Interface Builder, ce truc `` voir ça dans iOS7 et iOS6.1 côte à côte '' fonctionne parfaitement, montrant les tableaux parfaitement adaptés (une fois que les deltas iOS6/7 ont été correctement définis).
Cependant, en cours d'exécution sur un appareil ou un simulateur, il y avait un grand écart en haut du tableau, qui était le résultat d'une insertion de contenu (qui correspondait à peu près au delta vertical iOS6/7) qui était définie sur zéro dans la plume.
La seule solution que j'ai obtenue était dans viewWillAppear pour mettre [_tableView setContentInset: UIEdgeInsetsZero].
Un autre hack laid avec un joli résultat à l'écran .....