2017-03-21 2 views
0

J'essaie de créer un calque de dégradé personnalisé que je peux réutiliser dans l'Interface Builder pour mes différentes vues. J'ai créé la classe suivante:Sous-couche de l'élément personnalisé ne s'affiche pas dans le simulateur, rend dans le constructeur de l'interface

importation UIKit

@IBDesignable 
class MyGradientLayer: UIView { 

    let gradient = CAGradientLayer() 

    public override init(frame: CGRect) { 
     super.init(frame: frame) 

     gradient.colors = [startColor.cgColor, endColor.cgColor] 
     gradient.frame = self.bounds 
     gradient.locations = [0, 1] 
     self.layer.insertSublayer(gradient, at: 0) 
    } 

    public required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    @IBInspectable 
    public var startColor: UIColor = UIColor.init(red: 1, green: 0.364, blue: 0.22352, alpha: 1.0) { 
     didSet { 
      gradient.colors = [startColor.cgColor, endColor.cgColor] 
     } 
    } 

    @IBInspectable 
    public var endColor: UIColor = UIColor.init(red: 1, green: 0.1607, blue: 0.40392, alpha: 1.0) { 
     didSet { 
      gradient.colors = [startColor.cgColor, endColor.cgColor] 
     } 
    } 

    override func layoutSubviews() { 
     gradient.frame = self.bounds 
     gradient.locations = [0, 1] 
     super.layoutSubviews() 
    } 

} 

J'ai ensuite ajouté un UIView à mon ViewController et de définir la classe à MyGradientLayer dans l'inspecteur d'identité. Ma belle petite vue en dégradé est alors très bien rendue dans Interface Builder. Je vais de l'avant et fixe les contraintes pour occuper tout l'écran (j'ai essayé les contraintes manuelles et automatiques). Tout va bien, non? Non, il ne restitue pas la couche de gradient dans le simulateur. Cependant, je sais que la vue est là et est mise sur l'écran, parce que je peux définir la couleur d'arrière-plan de l'UIView dans IB, et cela se voit sur tout l'écran.

Aucune idée de la raison pour laquelle le calque de dégradé dans mon UIView personnalisé n'est pas rendu dans le simulateur?

Merci!

Répondre

0

Voir ce qui se passe si vous changez le « init » comme suit:

public override init(frame: CGRect) { 
    super.init(frame: frame) 
    self.commonInit() 
} 

public required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    self.commonInit() 
} 

func commonInit() { 

    gradient.colors = [startColor.cgColor, endColor.cgColor] 
    gradient.frame = self.bounds 
    gradient.locations = [0, 1] 
    self.layer.insertSublayer(gradient, at: 0) 

} 

Selon la façon dont il est utilisé, vous devrez peut-être définir un indicateur pour empêcher commonInit d'être appelé plus d'une fois. Essayez-le et voyez.

+0

C'était tout. En fait, je viens de comprendre et est venu mettre à jour la question. Quand Interface Builder l'affiche, il utilise l'init (frame), mais quand il est réellement rendu, il utilise la version du codeur. Je ne sais pas pourquoi (honnêtement, tant de choses me sont compliquées dans cet environnement) mais c'était la solution! –