40 votes

ios10: viewDidLoad largeur/hauteur n'est pas initialisé correctement

Depuis la mise à jour XCode8 GM et ios10, tous mes vues créées via l'Interface Builder ne sont pas initialisé correctement jusqu'à ce beaucoup, beaucoup plus tard que prévu. Ce qui signifie dans le viewDidLoad, cellForRowAtIndexPath, viewWillAppear, etc, la taille d'image est définie sur {1000,1000} pour chaque vue. À un certain moment, ils semblent correctes, mais son beaucoup trop tard.

Le premier problème rencontré est avec les communes de l'arrondissement des coins à défaut travers le conseil d'administration:

view.layer.cornerRadius = view.frame.size.width/2

Outre les problèmes apparaissent pour tout ce qui repose sur la taille d'image pour faire des calculs dans le code.

cellForRowAtIndexPath 

Pour cellForRowAtIndexPath, la taille d'image initiale échoue sur le tableau d'affichage, mais alors fonctionne très bien une fois que vous faites défiler. willDisplayCell:forRowAtIndexPath n'a pas la bonne taille de l'image soit.

J'ai codé en dur quelques valeurs, mais ce n'est évidemment très mauvais code de pratique, ainsi que d'assez nombreuses dans mes projets.

Est-il un moyen ou un endroit pour obtenir de corriger les tailles de cadre?

MODIFIER

J'ai découvert que l'utilisation de la hauteur/largeur de la contrainte à la place du châssis largeur hauteur est plus fiable. Cela peut ajouter la surcharge d'avoir besoin de beaucoup de nouveaux IBOutlets de relier la hauteur/largeur de contraintes sur les éléments bien.

Pour l'instant j'ai créé une UIView catégorie qui me permet d'accéder à la Vue de la hauteur/largeur de contraintes directement, sans IBOutlets. Pour réduire au minimum l'utilisation de la petite boucle ne devrait pas être un gros problème. Résultats non garantis pour les IB éléments sans que la largeur/hauteur des contraintes encore créé de toute évidence. Probablement renvoie 0 au mieux pour la constante, ou pire. Aussi, si vous n'avez pas la hauteur/largeur de la contrainte et de votre point de vue est dimensionné de façon dynamique en fonction avant/après de contraintes, cela ne fonctionne pas.

-viewDidLoad semble avoir corriger la taille de l'image, mais se traduit souvent par un changement de visuel de l'INTERFACE utilisateur si vous faites des modifications ici.

UIView+WidthHeightConstraints.h

@interface UIView (WidthHeightConstraints)

-(NSLayoutConstraint*)widthConstraint;
-(NSLayoutConstraint*)heightConstraint;
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute;

@end

UIView+WidthHeightConstraints.m

#import "UIView+WidthHeightConstraints.h"

@implementation UIView (WidthHeightConstraints)

-(NSLayoutConstraint*)widthConstraint{
    return [self constraintForAttribute:NSLayoutAttributeWidth];
}
-(NSLayoutConstraint*)heightConstraint {
    return [self constraintForAttribute:NSLayoutAttributeHeight];
}
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute {
    NSLayoutConstraint *targetConstraint = nil;
    for (NSLayoutConstraint *constraint in self.constraints) {
        if (constraint.firstAttribute == attribute) {
            targetConstraint = constraint;
            break;
        }
    }
    return targetConstraint;
}

@end

EDIT 2

La catégorie ci-dessus a prouvé que partiellement efficaces. Principalement parce que ios semble ajout automatique d'un couple supplémentaire de la hauteur/largeur de la contrainte de doublons, qui sont de type NSContentSizeLayoutConstraint, qui sont en fait pas la même taille que la normale de la contrainte. Le NSContentSizeLayoutConstraint est aussi une classe privée donc je ne peux pas faire isKindOfClass de filtre. Je n'ai pas trouvé un autre moyen efficace de tester pour ceux encore. C'est gênant.

30voto

pedrouan Points 256

Les problèmes les plus courants que vous décrivez font leur apparition dans iOS 10 seulement et peut être résolu par l'ajout de cette ligne (si nécessaire):

self.view.layoutIfNeeded()

juste au-dessus du code, qui est responsable de l'évolution de la contrainte, de la couche.cornerRadius etc.

OU

placez votre code en matière de cadres / couches en viewDidLayoutSubviews() méthode:

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()
    view.layer.cornerRadius = self.myView.frame.size.width/2
    view.clipsToBounds = true

    ... etc
}

16voto

Bhavik Bhagat Points 736

Nous avons créé un radar (28342777 (marqué en double pour 28221021 mais Ouverte)) pour le même problème et la réponse que nous avons obtenu comme ci-dessous:

"Merci d'avoir signalé le problème. Pourrions-nous obtenir plus d'informations sur le profil d'affichage de l'image? Dans Xcode 8, une contrainte, non égaré vue n'enregistre plus d'un cadre afin de réduire les différences et de soutien mettre à jour automatiquement les images de l'IB. Au moment de l'exécution, ces points de vue obtenir décodé avec un espace réservé à la taille de 1000x1000, mais sont résolus après la première mise en page. Pourrait l'image sera attribué avant le début de la mise en page, et serait d'assigner l'image à l'affichage de l'image après la première mise en page de l'adresse de ce cas? Veuillez envoyer un échantillon pour nous aider à analyser. merci!"

À l'heure actuelle, nous avons fourni l'exemple de projet. Mes observations:

  • Le problème que nous avions utilisée pour XIBs qui sont convertis à partir de Xcode 7.x pour Xcode 8.x
  • Si nous avons volontairement briser la contrainte dans XIB puis viewDidLoad obtiendrez attendus de la hauteur et de la largeur et de ne pas 1000x1000.
  • Pour nous c'était une UIImageView sur qui nous ont été appliquer un peu de superposition pour rendre circulaire et l'utilisation de masksToBounds. Si l'on masksToBounds = N alors nous avons tout fonctionnait bien.

Si Apple affirme qu'il est en train de devenir un standard de Xcode 8 que les points de vue seront mis à 1000x1000, le comportement ne semble pas être compatible.

Espérons que cette aide.

6voto

allen Points 276

J'ai rencontré le même problème et essayer de le résoudre sans succès en se référant suggestions ci-dessus.

Il semble qu'il devrait être un bug pour Apple à résoudre. J'ai enfin trouver une solution en changeant d'enregistrer mon XIB document Xcode 7.x format et mon INTERFACE de retour à la normale.

Jusqu'à ce que Apple libérant un correctif, je n'ai pas envie de passer mon temps sur le piratage c'.

enter image description here enter image description here

2voto

942v Points 21

Qu'en faisant ceci:

- (NSLayoutConstraint*)widthConstraint{
    return [self constraintForAttribute:NSLayoutAttributeWidth];
}

- (NSLayoutConstraint*)heightConstraint {
    return [self constraintForAttribute:NSLayoutAttributeHeight];
}

- (NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute {
    NSLayoutConstraint *targetConstraint = nil;
    for (NSLayoutConstraint *constraint in self.constraints) {
        //NSLog(@"constraint: %@", constraint);
        if (![constraint isKindOfClass:NSClassFromString(@"NSContentSizeLayoutConstraint")]) {
            if (constraint.firstAttribute == attribute) {
                targetConstraint = constraint;
                break;
            }
        }
    }
    return targetConstraint;
}

2voto

madboy Points 948

Vous ne devez jamais compter sur le calendrier de quand une vue est layed dehors. Si cela a fonctionné pour vous avant, puis hors de la chance pure. Il y a très peu de garanties à ce sujet dans UIKit. Si vous comptez sur quelque chose de l'adoption de la taille de votre point de vue, la bonne chose à faire est de remplacer layoutSubviews en que de consulter et de régler vos affaires là-bas.

Même après que votre vue est entièrement affiché sur l'écran, il y a encore beaucoup de conditions qui peuvent provoquer la taille de l'affichage pour changer. Par exemple: Double hauteur de la barre d'état, le multitâche sur l'iPad, l'appareil de rotation, pour n'en nommer que quelques-uns. Donc, il ne l'est jamais une bonne idée de le faire, cadre grille liée à des changements, à un moment donné dans le temps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X