web-dev-qa-db-fra.com

clipsToBounds empêche UIImage de s'afficher dans iOS10 et XCode 8

J'ai basculé mon projet vers de nouvelles versions bêta d'iOS 10 et de XCode 8. Dans les trois domaines de mon application où j'utilise:

imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true

Les images associées ne s'affichent pas du tout. J'ai essayé de nettoyer le projet ainsi que le dossier de construction, redémarrer l'appareil, essayer différents simulateurs, rajouter l'imageView, définir par programmation le UIImage associé au lieu d'en choisir un parmi les actifs.

La suppression de la ligne clipsToBounds montre l'image rectangulaire, que masksToBounds soit true ou false. Comment puis-je créer une image circulaire dans XCode8/iOS10?

Edit: Le projet est Swift 2.x et pas encore mis à jour vers Swift 3.0 syntaxe.

28
cloudcal

J'ai eu le même problème et appeler layoutIfNeeded avant que tout le coin arrondi/clipsToBounds ne corrige le problème. iOS 10 GM avec xcode 8 GM provoque la disparition des vues en raison des coins arrondis et des clipsToBounds

44
Pranoy C

Ce problème m'est également arrivé.

J'ai déplacé ces codes imageView.layer.cornerRadius = imageView.frame.size.width/2 De - (void)awakeFromNib vers - (void)drawRect:(CGRect)rect et ce problème a disparu.

Mon imageView est dimensionnée par mise en page automatique. Je pense que la hauteur et la largeur ne sont pas décidées lors du réveil de nib sur iOS 10.

6
VictorJi

Cela semble être dû à un nouveau bogue depuis iOS 10 et Xcode 8 où les vues sont initialisées à la taille 1000x1000 et lorsque vous essayez de définir le rayon du coin à la moitié de votre cadre, il le place à 500 à la place. Ceci est documenté plus loin dans cette question ici: Depuis Xcode 8 et iOS10, les vues ne sont pas dimensionnées correctement sur viewDidLayoutSubviews . Ma raison de penser que c'est la correction du problème 1000x1000 pour appeler des sous-vues de mise en page avant de faire quoi que ce soit qui nécessite des tailles pour quelque chose qui a été construit sur le générateur d'interface.

2
Trever123

J'avais ImageView qui est de forme entièrement circulaire. Voici le code:

//MARK:- Misc functions
func setProfileImage() {
    imgProfile.layer.masksToBounds = false
    imgProfile.layer.cornerRadius = imgProfile.frame.size.height/2
    imgProfile.clipsToBounds = true
    imgProfile.contentMode = UIViewContentMode.ScaleToFill
} 

Cela fonctionne bien dans iOS 9. Cependant, in iOS 10 Xcode 8 the ImageView disappears. Après le débogage a constaté que ClipsToBound est coupable.

Ainsi, le code placé dans viewDidLayoutSubviews() a résolu le problème.

override func viewDidLayoutSubviews() {
    setProfileImage()
}

Vous pouvez également utiliser self.view.layoutIfNeeded()

1
Jayprakash Dubey

J'ai eu le même problème. Ne s'affiche pas sur le téléphone, mais parfait sur le Storyboard et le débogueur d'interface utilisateur. Cela fonctionnait également lorsque je mettais le projet "Ouvre avec Xcode 7" au lieu de 8, mais ce n'était pas une solution satisfaisante. J'ai donc creusé et découvert le problème. Le problème était avec une classe ressemblant à ceci:

@IBDesignable public class MyButton: UIButton {

   @IBInspectable var styleName: String = "" {
        didSet {
            switch styleName {
            case "RoundedLight":
                tintColor = UIColor.lightPinkColor()
                layer.borderColor = UIColor.whiteColor().CGColor
                layer.borderWidth = 1
                layer.masksToBounds = true
            default:
                break
            }
        }
    }

    override public func layoutSubviews() {
        super.layoutSubviews()

        switch styleName {
            case "RoundedLight":
                layer.cornerRadius = frame.height / 2
            default:
                break
        }
    }
}

Je l'ai changé en cela et cela fonctionne maintenant:

@IBDesignable public class MyButton: UIButton {

   @IBInspectable var styleName: String = "" {
        didSet {
            layoutIfNeeded()
        }
    }

    override public func layoutSubviews() {
        super.layoutSubviews()

        switch styleName {
        case "RoundedLight":
            tintColor = UIColor.lightPinkColor()
            layer.borderColor = UIColor.whiteColor().CGColor
            layer.borderWidth = 1
            layer.cornerRadius = frame.height / 2
            layer.masksToBounds = true
        default:
            break
        }
    }
}

Notez que rien de ce qui précède n'a fonctionné pour moi, et je veux dire:

  • Appel de layoutIfNeeded dans la layoutSubviews()
  • Appel de layoutIfNeeded dans le awakeFromNib de mon bouton (ou ma cellule contenant le bouton)
  • Appel de layoutIfNeeded dans le layoutSubview de ma cellule
  • Appel de contentView.layoutIfNeeded() dans le awakeFromNib de ma cellule
  • Appel de view.layoutIfNeeded() dans mon contrôleur de vue
1
Livio

Il peut s'agir d'un problème de mise en page. Définir clipToBounds sur false afficherait l'image même si sa taille est nulle. Pouvez-vous imprimer le frame de vos images?

Si vous définissez les propriétés cornerRadius et clipToBounds dans viewDidLoad, essayez de le faire dans viewDidLayoutSubviews().

Vous pouvez également essayer d'appeler self.view.layoutIfNeeded().

0
Yann Bodson

En utilisant obj-c, le déplacement de la syntaxe de viewDidLoad vers viewDidLayoutSubviews a fonctionné pour moi.

0
Teffi

Je viens d'implémenter l'arrondi des coins comme celui-ci

@implementation RoundImageView

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
        [self addObserver:self
               forKeyPath:@"bounds"
                  options:NSKeyValueObservingOptionNew
                  context:(__bridge void * _Nullable)(self)];
    }
    return self;
}

-(void)dealloc
{
    [self removeObserver:self
              forKeyPath:@"bounds"
                 context:(__bridge void * _Nullable)(self)];
}

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary<NSString *,id> *)change
                      context:(void *)context
{
    if(context == (__bridge void * _Nullable)(self) && object == self && [keyPath isEqualToString:@"bounds"])
    {
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
    }
}

@end

donc je toujours ont des coins bien arrondis. Et je n'ai eu aucun problème lors de la mise à niveau vers iOS10 et XCode8

0
andrey.krukovskiy

Je pense que le problème se produit parce que nous avons défini les sous-vues des coins ronds et des clips comme l'a dit @Pranoy C.

J'ai résolu les problèmes en utilisant layoutIfNeeded pour la cellule my tableview montrant la photo de profil d'un utilisateur. Je veux m'assurer que l'image est au coin de la rue

Le code est le suivant: - (void) awakeFromNib {[super awakeFromNib]; [self layoutIfNeeded];

[self.inputIndicator_imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.profile_pic_edit_imageView.layer.cornerRadius = self.profile_pic_edit_imageView.frame.size.width/2;
self.profile_pic_edit_imageView.layer.borderWidth = 1.0;
self.profile_pic_edit_imageView.layer.borderColor = GRAY_COLOR_SUPER_LIGHT.CGColor;
self.profile_pic_edit_imageView.clipsToBounds = YES;}
0
wong wai