Ich habe eine UIView
, die ungefähr 8 verschiedene CALayer
-Sublayer zu ihrer Ebene hinzugefügt hat . Wenn ich die Grenzen der Ansicht ändere (animiert), dann schrumpft die Ansicht selbst (ich habe sie mit einer backgroundColor
überprüft), aber Die Größe der Sublayer bleibt unverändert .
Wie löse ich das?
Ich habe den gleichen Ansatz verwendet wie Solin, aber in diesem Code ist ein Tippfehler enthalten. Die Methode sollte sein:
- (void)layoutSubviews {
// resize your layers based on the view's new bounds
mylayer.frame = self.bounds;
}
Für meine Zwecke wollte ich, dass der Sublayer immer die volle Größe der übergeordneten Ansicht hat. Fügen Sie diese Methode in Ihre Ansichtsklasse ein.
Da CALayer auf dem iPhone keine Layout-Manager unterstützt, denke ich, dass Sie die Hauptebene Ihrer Ansicht zu einer benutzerdefinierten CALayer-Unterklasse machen müssen, in der Sie layoutSublayers
überschreiben, um die Frames aller Sublayer festzulegen. Sie müssen auch die +layerClass
-Methode Ihrer Ansicht überschreiben, um die Klasse Ihrer neuen CALayer-Unterklasse zurückzugeben.
Ich habe dies in der UIView verwendet.
-(void)layoutSublayersOfLayer:(CALayer *)layer
{
if (layer == self.layer)
{
_anySubLayer.frame = layer.bounds;
}
super.layoutSublayersOfLayer(layer)
}
Funktioniert bei mir.
Ich hatte das gleiche Problem. In der Ebene einer benutzerdefinierten Ansicht fügte ich zwei weitere Unterebenen hinzu. Um die Größe der untergeordneten Layer zu ändern (wenn sich die Grenzen der benutzerdefinierten Ansicht ändern), habe ich die Methode layoutSubviews
meiner benutzerdefinierten Ansicht implementiert. Innerhalb dieser Methode aktualisiere ich einfach den Frame jedes Sublayers, um ihn an die aktuellen Grenzen der Ebene meiner Subansicht anzupassen.
Etwas wie das:
-(void)layoutSubviews{
//keep the same Origin, just update the width and height
if(sublayer1!=nil){
sublayer1.frame = self.layer.bounds;
}
}
Swift 3 Version
Fügen Sie in der benutzerdefinierten Zelle folgende Zeilen hinzu
Zuerst deklarieren
let gradientLayer: CAGradientLayer = CAGradientLayer()
Fügen Sie dann folgende Zeilen hinzu
override func layoutSubviews() {
gradientLayer.frame = self.YourCustomView.bounds
}
Die wörtliche Antwort auf diese Frage:
ist das besser oder schlechter
needsDisplayOnBoundsChange
der Standardwert ist in CALayer
auf false gesetzt.
lösung,
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
}
}
In der Tat leite ich Sie zu dieser Qualitätssicherung
https://stackoverflow.com/a/47760444/294884
was erklärt, was zum Teufel die kritische Einstellung contentsScale
macht; Sie müssen das normalerweise gleich einstellen, wenn Sie needsDisplayOnBoundsChange einstellen.
Wie [Ole] schrieb, unterstützt CALayer keine Autoresizing-Funktion für iOS. Sie sollten also das Layout manuell anpassen. Meine Option bestand darin, den Rahmen der Ebene innerhalb von iOS 7 und früheren Versionen anzupassen.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
oder (ab iOS 8)
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato