如何替换当前的CALayer?

3
我是一个有用的助手,可以将文本翻译成中文。
我在Swift中有一个简单的应用程序。它有一个返回带有渐变背景的CALayer的函数。
当点击一个按钮时,我使用以下代码:
view.layer.insertSublayer(myGradientLayer, at: 0)

这段文本的意思是:代码运行正常,图层也能正确绘制。但是,如果我稍后想通过点击第二个按钮来更改颜色,就无法再更改索引为0的图层的颜色了。如果我使用相同的代码,什么都不会发生。我错过了什么?是的,我调用了view.setNeedsDisplay()。

1
是的,因为您的上一层将位于顶部... 如何? 好吧,有很多选项可以解决这个问题... 初始化时将CALayer作为成员并着色,然后仅插入一次,怎么样? - Coldsteel48
5个回答

4

根据文档,子层按照从后往前的顺序列出,因此每次在索引0处添加一个图层,它将位于前一个图层之下。第一层能与你协同工作是因为它是唯一的图层,但是你放置在它之后索引0处的任何图层都将低于第一层。


4

这里的两个答案都是正确的,非常感谢。

答案是:

view.layer.sublayers?[0].removeFromSuperLayer()
view.layer.insertSubLayer(MyLayer, at: 0)
view.setNeedsDisplay()

因此,在我实际调用上述方法之前,我需要像其中一个答案建议的那样在init方法中添加一层。


1
这是最好、最明显/简单的答案!我甚至给我的子层命名,然后通过名称将其删除。 - kalafun

2
我会给我的子图层命名为myLayer.name = "myLayer",然后在用它替换另一个图层之前调用一个函数。最初的回答。
    _ = layer.sublayers?.map {
        if $0.name == "myLayer" {
           $0.removeFromSuperlayer()
       }
    }
    layer.insertSublayer(myLayer, at: 0)

0
在需要类似功能时遇到了这个问题。 我的最终解决方案是定义一个新的类MyCALayer,它继承自CALayer
class MyCALayer : CALayer {
     var tag:Int?
     override init() {
         super.init()
     }

     required init?(coder aDecoder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }
}

然后在创建图层时,给它分配一个标签。下次需要替换它时,您可以循环遍历所有视图的子层,并找到先前添加的相应图层。

  if let sublayers = view.layer.sublayers {
        for layer in sublayers {
            if let mylayer = layer as? MyCALayer,
                mylayer.tag == tag {
                mylayer.removeFromSuperlayer()
            }
        }
    }

如果有人遇到类似的问题,可以分享一下。


0

还有一个replaceSublayer(_ oldLayer: CALayer, with newLayer: CALayer)方法:

view.layer.replaceSublayer(theOldLayer, with: newLayer)

上述代码将旧视图替换为新视图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接