Alle sublagen van CALayer verwijderen

Ik heb problemen met het verwijderen van alle sublagen van de laag. Ik doe dit momenteel handmatig, maar dat brengt onnodige rommel met zich mee. Ik heb veel onderwerpen hierover gevonden in Google, maar geen antwoord.

Ik heb geprobeerd zoiets als dit te doen:

for(CALayer *laag in rootLayer.sublagen)
{
  [laag removeFromSublayer];
}

maar het werkte niet.

Ik heb ook geprobeerd rootLayer.sublayers te klonen in aparte NSArray, maar het resultaat was hetzelfde.

Enig idee?

Bewerken:

Ik dacht dat het nu werkt, maar ik had het mis. Het werkt goed met CALayers, maar het werkt niet met CATextLayers. Enig idee?


Antwoord 1, autoriteit 100%

De eenvoudigste manier om alle sublagen van een laag te verwijderen, is door de eigenschap van de sublaag in te stellen op nul:

rootLayer.sublayers = nil;


Antwoord 2, autoriteit 26%

Het volgende zou moeten werken:

for (CALayer *layer in [[rootLayer.sublayers copy] autorelease]) {
    [layer removeFromSuperlayer];
}

Antwoord 3, autoriteit 13%

[rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];

Antwoord 4, autoriteit 13%

Swift (korte versie):

layer.sublayers?.forEach { $0.removeFromSuperlayer() }


Antwoord 5, autoriteit 4%

Het aanroepen van rootLayer.sublayers = nil;kan een crash veroorzaken (bijvoorbeeld als u onder iOS 8 removeFromSuperview twee keer aanroept in de view die eigenaar is van rootLayer).

De juiste manier zou moeten zijn:

[[rootLayer.sublayers copy] makeObjectsPerformSelector:@selector(removeFromSuperlayer)]

De aanroep van copyis nodig zodat de array waarop removeFromSuperlayeriteratief wordt aangeroepen niet wordt gewijzigd, anders wordt er een uitzondering gegenereerd.


Antwoord 6, autoriteit 2%

Het willekeurig verwijderen van alle sublagen veroorzaakt vervelende crashes in iOS 7, die veel later in de uitvoering van het programma kunnen optreden. Ik heb dit grondig getest met zowel rootLayer.sublayers = nilals [rootLayer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]. Er moet een door het systeem gecreëerde laag zijn die in de war raakt.

Je moet je eigen reeks lagen behouden en ze zelf verwijderen:

[myArrayOfLayersIAddedMyself makeObjectsPerformSelector:@selector(removeFromSuperlayer)];

Antwoord 7, autoriteit 2%

Ik moest dit doen in Xamarin/C#. Ik had een UITableViewCellmet een aantal CAShapeLayersvoor randen. Alle bovenstaande opties (inclusief het kopiëren van de array en vervolgens het verwijderen van lagen veroorzaakten een crash). De aanpak die voor mij werkte:

Bij het toevoegen van de CALayerheb ik het een naam gegeven:

   var border = new CALayer();
    border.BackgroundColor = color.CGColor;
    border.Frame = new  CGRect(x, y, width, height);
    border.Name = "borderLayerName";
    Layer.AddSublayer(border);

In PrepareForReuseop de UITableViewCellheb ik een kopie gemaakt van de eigenschap SubLayersen alles verwijderd dat overeenkwam met de naam die ik eerder had toegewezen:

   CALayer[] copy = new CALayer[Layer.Sublayers.Length];
    Layer.Sublayers.CopyTo(copy, 0);
    copy.FirstOrDefault(l => l.Name == "borderLayerName")?.RemoveFromSuperLayer();

Geen crashes.

Hopelijk helpt dit!


Antwoord 8

Hoe zit het met doen:

rootLayer.sublayers = @[];

Antwoord 9

Je kunt het zeker doen:
self.layer.sublayers=nil;
zoals voorgesteld door Pascal Bourque. Maar het is beter om de eigenschap setter voor sublagen aan te roepen:
[self.layer setSublayers:nil];
Om eventuele opruimproblemen te voorkomen.

Other episodes