快速覆盖 UIView 中的默认图层类型

Posted

技术标签:

【中文标题】快速覆盖 UIView 中的默认图层类型【英文标题】:Overriding default layer type in UIView in swift 【发布时间】:2015-07-23 21:49:11 【问题描述】:

我想在 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

【问题讨论】:

【参考方案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

【讨论】:

以上是关于快速覆盖 UIView 中的默认图层类型的主要内容,如果未能解决你的问题,请参考以下文章

AVPlayer

在 Swift 3.1 中为 UIView 子类设置默认外观而不覆盖 initialize()

UIView 上的圆形图层的 Swift 掩码

WPFのclipToBounds与maskToBounds的区别

如何快速覆盖 UIView.pointInside?

在后台线程上渲染新的 UIView 图层内容?