iOS核心动画:CALayer bringSublayerToFront?

ma1*_*w28 30 iphone core-animation objective-c calayer ios

我如何将a CALayer sublayer带到所有子层的前面,类似于-[UIView bringSubviewToFront]

Sha*_*ram 54

我很好奇为什么这些答案都没有提到CALayer上的zPosition属性.Core Animation会查看此属性以确定图层渲染顺序.值越高,越靠前.只要您的zPosition为0,这些答案都可以正常工作,但是为了轻松地将图层置于前面,将其zPosition值设置为高于所有其他子图层.


iva*_*oid 43

这是@ MattDiPasquale实现的变体,它更准确地反映了UIView的逻辑:

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

- (void) sendSublayerToBack:(CALayer *)layer
{
    [layer removeFromSuperlayer];
    [self insertSublayer:layer atIndex:0];
}
Run Code Online (Sandbox Code Playgroud)

注意:如果您不使用ARC,您可能希望[layer retain][layer release]两个函数的顶部和底部添加,以确保layer在保留count = 1的情况下不会意外地破坏.

  • 不需要`removeFromSuperlayer`方法,因为在调用`insertSublayer`时它将自动删除。 (2认同)

com*_*tos 8

正确的代码在这里

- (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];
}
Run Code Online (Sandbox Code Playgroud)


Vla*_*lad 8

斯威夫特 4 版本。
层本身具有的想法bringToFrontsendToBack方法。

#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)
   }
}
Run Code Online (Sandbox Code Playgroud)

用法:

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()
Run Code Online (Sandbox Code Playgroud)


ma1*_*w28 -6

我认为这样的方法不存在,但很容易推出自己的方法。

// 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];
}
Run Code Online (Sandbox Code Playgroud)

  • 可能是因为代码错误。不使用参数层。渐变层未定义。不需要 superlayer 调用,因为层参数的 superlayer 是 self。ivanzoid 已发布更正的代码。 (8认同)