web-dev-qa-db-fra.com

La vue Tableau iOS 7 ne parvient pas à ajuster automatiquement l'encart de contenu

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.

Table view get blocked

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é.

enter image description here

Conclusion

  1. Les deux contrôleurs de vue règlent automatiquement les ScrollViewInsets sur OUI
  2. Le projet n'utilise pas de storyboard
  3. Le premier est créé sur Xcode 4.6, le second est nouvellement créé sur Xcode 5
  4. J'ai comparé deux classes xib et code, pas très différent
38
Tony Fung Choi Fung

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

55

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
        };
    }
}
47

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.

3
awulf

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.

2
Ell Neal

@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
}
1
Avt

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 .....

0
Peter