UIViewContentModeScaleAspectFill sans découpage

144

J'essaie de dessiner des images miniatures à une taille fixe (100x100) en utilisant UIImageView. J'ai défini la taille du cadre de ma vue d'image sur 100x100 et défini contentModesur UIViewContentModeScaleAspectFill.

Je crois comprendre que cela devrait entraîner le dessin de l'image à la taille que j'ai définie, et l'image remplira la zone de l'image et coupera toutes les parties de l'image qui sont en dehors de la taille que j'ai définie pour la vue de l'image. Cependant, l'image est toujours dessinée plus grande ou plus petite que la taille 100x100 que je lui ai définie.

Si je règle le contentModesur UIviewContentModeScaleToFill, l'image est dessinée à exactement 100x100, mais elle est déformée pour s'adapter à ces dimensions. Avez-vous des idées sur la raison pour laquelle le remplissage d'aspect n'est pas coupé comme prévu?

Voici mon code:

_photoView = [[UIImageView alloc] initWithImage:photoImage];
_photoView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:_photoView];

CGRect photoFrame = _photoView.frame;
photoFrame.size = CGSizeMake(100, 100);
_photoView.frame = photoFrame;

Pour mieux illustrer, voici une capture d'écran de ce que je vois. Les carrés verts UIViewcontiennent les éléments avec lesquels UIImageViewje travaille. J'ai défini leur couleur d'arrière-plan sur le vert et le cadre de la vue sur 100x100. À titre de test, les UIImageViewsdimensions sont de 50x50. Comme vous pouvez le voir, lorsque vous utilisez le ...AspectFill, les images ne sont pas dimensionnées à 50x50 et, dans certains cas, sont décalées de l'endroit où je les voudrais. Lors de l'utilisation ...ScaleToFill, ils sont dimensionnés correctement, mais l'image est déformée.

Capture d'écran illustrant le problème

Josh Buhler
la source

Réponses:

352

Pouvez-vous essayer de définir le clip aux limites

[_photoview setClipsToBounds:YES];

Ou directement dans votre Storyboard / Xib si vous pouvez:

entrez la description de l'image ici

imthi
la source
10
C'était ça - merci. (J'ai ajouté la capture d'écran ci-dessus pour mieux montrer ce que je voyais, plus à titre d'exemple si quelqu'un d'autre rencontre ce problème.)
Josh Buhler
3
Dans InterfaceBuilder, renommé (sans aide) en "Clips subviews" (NB: dans ce cas, il ne clibe pas "subviews", le nom est faux: il clip SELF AND subviews)
Adam
3
Cochez l'option 'Clip Subviews' dans le fichier NIB fait la même chose. À votre santé.
codeburn
Mais qu'en est-il si vous souhaitez ajouter une ombre en utilisant la propriété CALayer: (ajouter une autre vue derrière elle n'est pas idéale pour moi
Rambatino
Si vous utilisez la mise en page automatique comme moi, il y a une autre cause possible, qui est NSLayoutConstraint "UIView-Encapsulated-Layout-Height" rompant les contraintes de taille UIImageView.
ewiinnnnn
8

Si vous souhaitez approfondir vos connaissances, il existe un très bon article sur le rendu de la pile iOS UIView . Il existe également un article plus détaillé sur l' ensemble du pipeline de dessin .

En résumé:

  1. Rastérisation - Tout le contenu de la vue est pixellisé (dessiné ou un tampon de pixels hors écran) dans l'espace de coordonnées des limites de la vue. Cela peut être des données d'image ou un dessin personnalisé (c'est-à-dire drawRect:) mais du contenu de sous-vue. Cette rastérisation prend en compte la contentModepropriété.

    Tout ce qui se trouve en dehors des limites d'une vue est ignoré.

  2. Composition - Les résultats sont composés (dessinés les uns sur les autres) de la sous-vue aux super-vues. Cela utilise la propriété frame de la sous-vue.

    Si la clipsToBoundspropriété est YESsur la vue supervisée, elle supprimera le contenu de la sous- vue en dehors de ses limites.

Robert
la source
2

eu le même problème et il a été résolu en cochant "Sous-vues de clip".

L'image s'affichait correctement pour toutes les vues (3.5,4,4.7,5.5, ipad) dans l'aperçu du storyboard mais pas dans le simulateur.

Après avoir coché «Clip Subviews», le problème a été résolu. :)

Brackston Mayhall
la source
1

Cocher "Sous-vues de clip" directement dans le Storyboard / Xib a également fonctionné pour moi. entrez la description de l'image ici

Maxime T
la source
0

Mes sous-vues étaient redimensionnées et j'ai réalisé que c'était parce que le xib avait une mise en page automatique: entrez la description de l'image ici

alistair
la source
0

Si tout échoue,

effectuez les clips jusqu'aux limites dans la méthode viewDidLayoutSubviews.

Exemple :

  override func viewDidLayoutSubviews() {

    imageProfile.layer.cornerRadius = imageProfile.bounds.size.width/2
    imageProfile.clipsToBounds = true
    imageProfile.layer.masksToBounds = true
 }
bharathi kumar
la source