Frage CALayers wurde bei der Änderung der UIView-Grenze nicht in der Größe geändert. Warum?


Ich habe ein UIView das hat ungefähr 8 verschiedene CALayer Sublayer zu seiner Ebene hinzugefügt. Ob Ich ändere die Grenzen der Ansicht (animiert), dann schrumpft die Ansicht selbst (ich überprüfte es mit einem backgroundColor), aber Die Größe der Unterschichten bleibt unverändert.

Wie löst man das?


76
2018-03-23 22:43


Ursprung


Antworten:


Ich habe den gleichen Ansatz verwendet wie Solin, aber es gibt einen Tippfehler in diesem Code. 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 immer, dass der Sublayer die volle Größe der Elternansicht hat. Setzen Sie diese Methode in Ihre Sichtklasse.


118
2017-11-04 15:37



Da CALayer auf dem iPhone keine Layout-Manager unterstützt, denke ich, dass Sie die Hauptschicht Ihrer Ansicht zu einer benutzerdefinierten CALayer-Unterklasse machen müssen, in der Sie überschreiben layoutSublayers um die Frames aller Sublayer zu setzen. Sie müssen auch Ihre Ansicht überschreiben +layerClass Methode, um die Klasse Ihrer neuen CALayer-Unterklasse zurückzugeben.


23
2018-03-24 00:40



Ich habe das in der UIView verwendet.

-(void)layoutSublayersOfLayer:(CALayer *)layer
{
    if (layer == self.layer)
    {
        _anySubLayer.frame = layer.bounds;
    }

super.layoutSublayersOfLayer(layer)
}

Funktioniert bei mir.


10
2018-02-27 03:39



Ich hatte das gleiche Problem. In der Ebene einer benutzerdefinierten Ansicht habe ich zwei weitere Unterlayer hinzugefügt. Um die Größe der Sublayer zu ändern (jedes Mal, wenn sich die Grenzen der benutzerdefinierten Ansicht ändern), habe ich die Methode implementiert layoutSubviews meiner benutzerdefinierten Ansicht; Innerhalb dieser Methode aktualisiere ich einfach den Rahmen jedes Sublayers, damit er mit den aktuellen Grenzen der Ebene meiner Subview übereinstimmt.

Etwas wie das:

-(void)layoutSubviews{
   //keep the same origin, just update the width and height
   if(sublayer1!=nil){
      sublayer1.frame = self.layer.bounds;
   }
}

8
2017-07-28 08:21



Schnelle 3 Version 

Fügen Sie in Benutzerdefinierte Zelle folgende Zeilen hinzu

Erklären Sie zuerst

let gradientLayer: CAGradientLayer = CAGradientLayer()

Dann füge folgende Zeilen hinzu

override func layoutSubviews() {
    gradientLayer.frame = self.YourCustomView.bounds
}

3
2018-06-08 10:38



2017

Die wörtliche Antwort auf diese Frage:

"CALayers wurde bei der Änderung der UIView-Grenze nicht in der Größe geändert. Warum?"

ist das für besser oder schlechter

needsDisplayOnBoundsChange

Standardwert ist false in CALayer.

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, ich weise Sie auf diese QA

https://stackoverflow.com/a/47760444/294884

was erklärt, was zum Teufel das Kritische contentsScale Einstellung tut; In der Regel müssen Sie dies ebenfalls festlegen, wenn Sie needsDisplayOnBoundsChange festlegen.


2
2017-12-11 17:56



Wie [Ole] schrieb CALayer unterstützt Autoresizing auf iOS nicht. Sie sollten das Layout also manuell anpassen. Meine Option war, den Rahmen der Ebene anzupassen (iOS 7 und früher)

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

oder (ab iOS 8)

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinato

0
2018-03-01 12:59