iOS Core Animation: CALayer bringSublayerToFront?

前端 未结 8 1694
情深已故
情深已故 2020-12-25 12:28

How do I bring a CALayer sublayer to the front of all sublayers, analogous to -[UIView bringSubviewToFront]?

相关标签:
8条回答
  • 2020-12-25 12:36

    I'm curious why none of these answers mention the zPosition attribute on CALayer. Core Animation looks at this attribute to figure out layer rendering order. The higher the value, the closer it is to the front. These answers all work as long as your zPosition is 0, but to easily bring a layer to the front, set its zPosition value higher than all other sublayers.

    0 讨论(0)
  • 2020-12-25 12:42

    Swift 4 version.
    Idea that layer itself has bringToFront and sendToBack methods.

    #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)
       }
    }
    

    Usage:

    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()
    
    0 讨论(0)
  • 2020-12-25 12:43

    Right code here

    - (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];
    }
    
    0 讨论(0)
  • 2020-12-25 12:54

    This is variation of @MattDiPasquale's implementation which reflects UIView's logic more precisely:

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

    Note: if you don't use ARC, you may wish to add [layer retain] at top and [layer release] at bottom of both functions to make sure layer is not accidentally destructed in a case it has retain count = 1.

    0 讨论(0)
  • 2020-12-25 13:00

    This is the correct code:

    -(void)bringSubLayerToFront:(CALayer*)layer
    {
      [layer.superLayer addSubLayer:layer];
    }
    
    -(void)sendSubLayerToBack:(CALayer*)layer
    {
      [layer.superlayer insertSublayer:layer atIndex:0];
    }
    
    0 讨论(0)
  • 2020-12-25 13:00

    I don't think such methods exist, but it's easy to roll your own.

    // 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];
    }
    
    0 讨论(0)
提交回复
热议问题