clipsToBounds fait que UIImage ne s'affiche pas dans iOS10 & XCode 8

j'ai transféré mon projet sur de nouvelles versions bêta de iOS 10 et XCode 8. Dans les trois domaines de mon application où j'utilise:

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

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 divers simulateurs, ajouter à nouveau imageView, programmer le UIImage associé au lieu d'en choisir un parmi les actifs.

suppression la ligne clipsToBounds montre l'image rectangulaire indépendamment du fait que masksToBounds soit true ou false . Comment puis-je faire une image circulaire dans XCode8 / iOS10 ?

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

28
demandé sur cloudcal 2016-08-25 07:18:32

10 réponses

j'ai eu le même problème et j'ai appelé layoutIfNeeded avant que tout le coin arrondi / clipsToBounds truc fixe le problème. iOS 10 GM avec xcode 8 GM fait disparaître les vues à cause de roundedCorners & clipsToBounds

44
répondu Pranoy C 2017-05-23 12:02:30

, Ce problème m'est arrivé.

j'ai déplacé ce code imageView.layer.cornerRadius = imageView.frame.size.width/2 de - (void)awakeFromNib à - (void)drawRect:(CGRect)rect et ce problème a disparu.

mon imageView est dimensionné par autolayout. Je pense que la hauteur et la largeur ne sont pas décidés en se réveillant de nib sur iOS 10.

6
répondu VictorJi 2016-09-10 03:07:53

cela sonne comme si cela pouvait être dû à un nouveau bug depuis iOS 10 et Xcode 8 où les vues sont initialisées à la taille 1000x1000 et lorsque vous essayez de régler le rayon de coin à la moitié de votre cadre, il le règle à 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 le correctif à la question 1000x1000 il 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 constructeur d'interface.

2
répondu Trever123 2017-05-23 12:09:44

j'ai eu le même problème. Pas au téléphone, mais parfait pour le Storyboard et le débogueur. Il fonctionnait aussi quand je mettais le projet "open with Xcode 7" au lieu de 8 mais n'était pas une solution satisfaisante. J'ai donc creusé et trouvé 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 ceci 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 qu'aucun de ces éléments n'a fonctionné pour moi, et je veux dire :

  • appelant layoutIfNeeded dans le layoutSubviews()
  • appelant layoutIfNeeded dans le awakeFromNib de mon bouton (ou de ma cellule contenant le bouton)
  • appelant layoutIfNeeded dans le layoutSubview de ma cellule
  • appelant contentView.layoutIfNeeded() dans le awakeFromNib de ma cellule
  • appelant view.layoutIfNeeded() dans mon contrôleur de vue
1
répondu Livio 2016-09-22 19:41:38

J'ai eu ImageView qui est de forme entièrement circulaire. Ci-dessous 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 très bien dans iOS 9. Toutefois, in iOS 10 Xcode 8 the ImageView disappears. Après le débogage a trouvé que ClipsToBound est coupable.

ainsi placé le code dans viewDidLayoutSubviews() résolu la question.

override func viewDidLayoutSubviews() {
    setProfileImage()
}

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

1
répondu Jayprakash Dubey 2016-10-28 04:21:27

c'est peut-être un problème de mise en page. Mettre clipToBounds à false montrerait l'image même si sa taille est zéro. 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 aussi essayer d'appeler self.view.layoutIfNeeded() .

0
répondu Yann Bodson 2016-08-25 06:39:57

utilisant obj-c, déplacer la syntaxe de viewDidLoad à viewDidLayoutSubviews a fonctionné pour moi.

0
répondu Teffi 2016-09-15 14:32:39

je viens de mettre en œuvre l'arrondissement des coins comme ceci

@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

je toujours ont bien des coins arrondis. Et je n'avais pas de problème pour passer à iOS10 et XCode8

0
répondu andrey.krukovskiy 2016-09-21 14:51:50

je pense que le problème se produit parce que nous avons mis le coin rond et clip subviews comme @Pranoyc dit.

j'ai résolu les problèmes en utilisant layoutifneded pour la cellule my tableview montrant une image de profil de l'utilisateur. Je veux m'assurer que l'image est en angle rond

Le Code

est le suivant: - (vide)awakeFromNib { [super awakeFromNib]; [auto 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
répondu wong wai 2016-09-22 05:22:53

vous devez appeler layoutSubviews() sur la vue principale avant d'appeler imageView.cadre.taille.largeur

[self.view layoutSubviews];
imageView.layer.cornerRadius = imageView.frame.size.width/2
imageView.clipsToBounds = true
-1
répondu Leonardo Zanatta Barradas 2016-09-09 03:16:14