objective framework developer apple iphone objective-c ios core-animation calayer

iphone - framework - iOS Core Animation: CALayer bringSublayerToFront?



swift ios documentation (8)

¿Cómo traigo una CALayer sublayer al frente de todas las subcapas, análogamente a -[UIView bringSubviewToFront] ?


Código correcto aquí

- (void)bringSublayerToFront:(CALayer *)layer { CALayer *superlayer = layer.superlayer; [layer removeFromSuperlayer]; [superlayer insertSublayer:layer atIndex:[superlayer.sublayers count]]; } - (void)sendSublayerToBack:(CALayer *)layer { CALayer *superlayer = layer.superlayer; [layer removeFromSuperlayer]; [superlayer insertSublayer:layer atIndex:0]; }


Crea una categoría de CALayer así:

@interface CALayer (Utils) - (void)bringSublayerToFront; @end @implementation CALayer (Utils) - (void)bringSublayerToFront { CGFloat maxZPosition = 0; // The higher the value, the closer it is to the front. By default is 0. for (CALayer *layer in self.superlayer.sublayers) { maxZPosition = (layer.zPosition > maxZPosition) ? layer.zPosition : maxZPosition; } self.zPosition = maxZPosition + 1; } @end


Esta es una variación de la implementación de @ MattDiPasquale que refleja la lógica de UIView más precisamente:

- (void) bringSublayerToFront:(CALayer *)layer { [layer removeFromSuperlayer]; [self insertSublayer:layer atIndex:[self.sublayers count]]; } - (void) sendSublayerToBack:(CALayer *)layer { [layer removeFromSuperlayer]; [self insertSublayer:layer atIndex:0]; }

Nota : si no usa ARC, es posible que desee agregar [layer retain] en la parte superior y [layer release] en la parte inferior de ambas funciones para asegurarse de que la layer no se destruya accidentalmente en un caso en el que se haya mantenido la cuenta = 1.


Este es el código correcto:

-(void)bringSubLayerToFront:(CALayer*)layer { [layer.superLayer addSubLayer:layer]; } -(void)sendSubLayerToBack:(CALayer*)layer { [layer.superlayer insertSublayer:layer atIndex:0]; }


No creo que existan tales métodos, pero es fácil rodar los tuyos.

// CALayer+Additions.h @interface CALayer (Additions) - (void)bringSublayerToFront:(CALayer *)layer; - (void)sendSublayerToBack:(CALayer *)layer; @end // CALayer+Additions.m @implementation CALayer (Additions) - (void)bringSublayerToFront:(CALayer *)layer { CALayer *superlayer = self.superlayer; [self removeFromSuperlayer]; [superlayer insertSublayer:gradientLayer atIndex:[self.sublayers count]-1]; } - (void)sendSublayerToBack:(CALayer *)layer { CALayer *superlayer = self.superlayer; [self removeFromSuperlayer]; [superlayer insertSublayer:gradientLayer atIndex:0]; }


Puede implementar esta funcionalidad en una categoría en CALayer así:

CALayer + Extension.h

#import <QuartzCore/QuartzCore.h> typedef void (^ActionsBlock)(void); @interface CALayer (Extension) + (void)performWithoutAnimation:(ActionsBlock)actionsWithoutAnimation; - (void)bringSublayerToFront:(CALayer *)layer; @end

CALayer + Extension.m

#import "CALayer+Extension.h" @implementation CALayer (Extension) + (void)performWithoutAnimation:(ActionsBlock)actionsWithoutAnimation { if (actionsWithoutAnimation) { // Wrap actions in a transaction block to avoid implicit animations. [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; actionsWithoutAnimation(); [CATransaction commit]; } } - (void)bringSublayerToFront:(CALayer *)layer { // Bring to front only if already in this layer''s hierarchy. if ([layer superlayer] == self) { [CALayer performWithoutAnimation:^{ // Add ''layer'' to the end of the receiver''s sublayers array. // If ''layer'' already has a superlayer, it will be removed before being added. [self addSublayer:layer]; }]; } } @end

Y para un fácil acceso puede #import "CALayer+Extension.h" en el archivo Prefix.pch (encabezado precompilado) de su proyecto.


Tengo curiosidad por qué ninguna de estas respuestas menciona el atributo zPosition en CALayer. Core Animation mira este atributo para averiguar el orden de representación de la capa. Cuanto mayor sea el valor, más cerca está del frente. Todas estas respuestas funcionan siempre que su zPosition sea 0, pero para colocar una capa en la parte frontal, establezca su valor de zPosition más alto que el de todas las demás subcapas.


Versión Swift 4.
La idea de que la capa en sí misma tiene los métodos bringToFront y sendToBack .

#if os(iOS) import UIKit #elseif os(OSX) import AppKit #endif extension CALayer { func bringToFront() { guard let sLayer = superlayer else { return } removeFromSuperlayer() sLayer.insertSublayer(self, at: UInt32(sLayer.sublayers?.count ?? 0)) } func sendToBack() { guard let sLayer = superlayer else { return } removeFromSuperlayer() sLayer.insertSublayer(self, at: 0) } }

Uso:

let view = NSView(frame: ...) view.wantsLayer = true view.layer?.backgroundColor = NSColor.gray.cgColor let l1 = CALayer(...) let l2 = CALayer(...) view.layer?.addSublayer(l1) view.layer?.addSublayer(l2) l1.bringToFront()