【问题标题】:How to replace current CALayer如何替换当前的 CALayer
【发布时间】:2016-09-26 14:59:00
【问题描述】:

我有一个简单的 swift 应用程序。它有一个函数返回一个CALayer,它是一个带有渐变背景的图层。

单击按钮时,我使用以下代码:

view.layer.insertSublayer(myGradientLayer, at: 0)

效果很好并且可以正确绘制。但是,如果我稍后想通过单击第二个按钮来更改颜色,我将无法再更改索引 0 处图层的颜色。如果我使用相同的代码,则不会发生任何事情。我错过了什么?是的,我称之为 view.setNeedsDisplay()

【问题讨论】:

  • 是的,因为您的上一层将在顶部...如何?好吧,有很多选择可以解决这个问题... CALayer 作为成员并为其着色,而在 init 中仅插入一次或其他什么?

标签: ios objective-c swift macos


【解决方案1】:

来自文档The sublayers are listed in back to front order.so 每次您在索引 0 处添加一个图层时,它都会低于您之前的图层。第一层适用于您,因为它是唯一的层,但您在索引 0 处放置的任何层都将低于第一层

【讨论】:

    【解决方案2】:

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

    答案是:

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

    所以我需要在 init 方法中添加一个层,就像其中一个答案建议的那样,才能真正调用上述方法。

    【讨论】:

    • 这是最好、最明显/最简单的答案!我还为我的子图层命名,然后按名称删除它
    【解决方案3】:

    我会尽量将我的子层命名为 myLayer.name = "myLayer",然后在用它替换另一个层之前调用一个函数。

        _ = layer.sublayers?.map {
            if $0.name == "myLayer" {
               $0.removeFromSuperlayer()
           }
        }
        layer.insertSublayer(myLayer, at: 0)
    

    【讨论】:

      【解决方案4】:

      当我需要类似的功能时遇到这个问题。 我的最终解决方案是定义一个继承CALayer 的新类MyCALayer

      class MyCALayer : CALayer {
           var tag:Int?
           override init() {
               super.init()
           }
      
           required init?(coder aDecoder: NSCoder) {
               fatalError("init(coder:) has not been implemented")
           }
      }
      

      然后在创建图层时,为其分配一个标签。下次需要替换的时候,可以循环所有view的子层,找到之前添加的对应层。

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

      分享一下,以防其他人遇到类似问题。

      【讨论】:

        【解决方案5】:

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

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

        上面的代码用新视图替换了旧视图。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-01
          • 2019-07-10
          • 2020-12-02
          • 1970-01-01
          • 1970-01-01
          • 2017-12-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多