J'ai un UIView
qui a environ 8 sous-couches CALayer
différentes ajoutées à son calque . Si je modifie les limites de la vue (animé), la vue elle-même est réduite (je l'ai vérifiée avec un backgroundColor
), mais la taille des sous-couches reste inchangée .
Comment résoudre ceci?
J'ai utilisé la même approche que Solin, mais il y a une faute de frappe dans ce code. La méthode devrait être:
- (void)layoutSubviews {
// resize your layers based on the view's new bounds
mylayer.frame = self.bounds;
}
Pour mes besoins, j'ai toujours souhaité que la sous-couche ait la taille de la vue parent. Mettez cette méthode dans votre classe de vue.
Étant donné que CALayer sur l'iPhone ne prend pas en charge les gestionnaires de disposition, je pense que vous devez transformer le calque principal de votre vue en une sous-classe CALayer personnalisée dans laquelle vous remplacez layoutSublayers
pour définir les images de toutes les sous-couches. Vous devez également remplacer la méthode +layerClass
de votre vue pour renvoyer la classe de votre nouvelle sous-classe CALayer.
Je l'ai utilisé dans UIView.
-(void)layoutSublayersOfLayer:(CALayer *)layer
{
if (layer == self.layer)
{
_anySubLayer.frame = layer.bounds;
}
super.layoutSublayersOfLayer(layer)
}
Travaille pour moi.
J'ai eu le même problème. Dans la couche d'une vue personnalisée, j'ai ajouté deux sous-couches supplémentaires. Afin de redimensionner les sous-couches (chaque fois que les limites de la vue personnalisée changent), j'ai implémenté la méthode layoutSubviews
de ma vue personnalisée; Dans cette méthode, je viens de mettre à jour le cadre de chaque sous-couche afin qu'il corresponde aux limites actuelles du calque de ma sous-vue.
Quelque chose comme ça:
-(void)layoutSubviews{
//keep the same Origin, just update the width and height
if(sublayer1!=nil){
sublayer1.frame = self.layer.bounds;
}
}
Swift 3 Version
Dans la cellule personnalisée, Ajouter les lignes suivantes
Déclarer d'abord
let gradientLayer: CAGradientLayer = CAGradientLayer()
Puis ajoutez les lignes suivantes
override func layoutSubviews() {
gradientLayer.frame = self.YourCustomView.bounds
}
La réponse littérale à cette question:
est-ce pour le meilleur ou pour le pire
needsDisplayOnBoundsChange
la valeur par défaut est false dans CALayer
.
solution,
class CircularGradientViewLayer: CALayer {
override init() {
super.init()
needsDisplayOnBoundsChange = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override open func draw(in ctx: CGContext) {
go crazy drawing in .bounds
}
}
En effet, je vous dirige vers ce QA
https://stackoverflow.com/a/47760444/294884
ce qui explique, que diable fait le paramètre contentsScale
critique; vous devez généralement également définir cela lorsque vous définissez needsDisplayOnBoundsChange.
Comme [Ole] l'a écrit, CALayer ne prend pas en charge le redimensionnement automatique sur iOS. Donc, vous devez ajuster la mise en page manuellement. Mon option était d'ajuster le cadre de la couche dans (iOS 7 et versions antérieures)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
ou (à partir de iOS 8)
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato