【问题标题】:Overriding default layer type in UIView in swift快速覆盖 UIView 中的默认图层类型
【发布时间】:2026-02-07 05:30:01
【问题描述】:

我想在 swift 中子类化 UIView,并使用 CAShapeLayer 作为该子类的层类型 - 用 layerClass() 覆盖层类型。

如何访问 CAShapeLayer 中而不是 CALayer 中的属性 - 例如下面示例中的路径。下面的代码无法编译,因为 path 不是 CALayer 的成员。

override class func layerClass() -> AnyClass {
    return CAShapeLayer.self
}

override func awakeFromNib() {

    var path: UIBezierPath = UIBezierPath.init(ovalInRect: CGRectMake(0, 0, 30, 10))

    self.layer.path = path.CGPath
}

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    请注意,self.layer 总是在 UIView 中返回一个通用的 CALayer,因此您必须将其类型转换为您的特定类以确保它具有正确的类型。您可以执行以下操作以确保调用 CAShapeLayer 的路径而不是 CALayer 类类型。

       override class func layerClass() -> AnyClass {
            return CAShapeLayer.self
        }
    
        override func awakeFromNib() {
            guard let shapeLayer = self.layer as? CAShapeLayer else { return }
    
             let path: UIBezierPath = UIBezierPath.init(ovalInRect: CGRectMake(0, 0, 30, 10))
            shapeLayer.path = path.CGPath
        }
    

    【讨论】:

      【解决方案2】:

      似乎从 Swift 3 开始,答案是

      override public class var layerClass: Swift.AnyClass {
          get {
              return CAShapeLayer.self
          }
      }
      

      【讨论】:

      • 并确保将活动方案设置为在设备(甚至是通用设备)上构建,否则即使在尝试构建之前,您也会收到未解决的符号错误。
      【解决方案3】:

      投射图层,然后使用路径属性

       (self.layer as! CAShapeLayer).path = path.CGPath
      

      【讨论】:

        【解决方案4】:

        更简洁,来自documentation (Swift 4):

        override class var layerClass: AnyClass {
            return CAShapeLayer.self
        }
        

        【讨论】: