【问题标题】:CAShapeLayer doesn't show upCAShapeLayer 不显示
【发布时间】:2018-12-27 17:46:59
【问题描述】:

我正在尝试将CAShapeLayer 添加到视图中。但是当我将customView 添加到 ViewCONtroller 的视图中时,shapeLayer 没有出现。捕获层次结构表明该层甚至没有插入到视图中。代码如下:

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

override func didMoveToSuperview() {
        let diameter = min(self.frame.width, self.frame.height)
        let path = UIBezierPath(arcCenter: self.center, radius: diameter/2, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)
        let sLayer = CAShapeLayer()
        sLayer.frame = bounds
        sLayer.path = path.cgPath
        sLayer.fillMode = .backwards
        sLayer.fillColor = UIColor.blue.cgColor//bubbleColor?.cgColor
        layer.addSublayer(sLayer)
    }

在 ViewController 中:

override func viewDidLoad() {
        super.viewDidLoad()
        let node = Node(frame: CGRect(origin: self.view.center, size: CGSize(width: 250, height: 250)))
        self.view.addSubview(node)
...
}

我真的不明白发生了什么。请帮忙!

【问题讨论】:

  • 出于好奇,你为什么设置layerClass,然后添加CAShapeLayer。因此,您有两个完全不同的 CAShapeLayer 实例。这是你的意图吗?为什么要更改基数layerClass
  • 我在尝试不使用它。然后在这里得到了参考。我只是添加它并错误地复制到这里。 ??????
  • 好的。不用担心。如果您愿意,您可以使用layerClass 进行复制,但我们不会添加子层。这是一个或另一个。
  • 是的,我明白了。感谢您从两个角度解决问题。 Constraints 在这里发挥了至关重要的作用。

标签: ios uiview swift4 cashapelayer swift4.2


【解决方案1】:

我建议:

  1. init 中添加你的子层(所以它只添加一次);
  2. layoutSubviews 中配置其framepath(因此,如果调整大小,无论是通过约束还是其他机制,层都会相应地更新);
  3. 添加尺寸基于当前视图大小的子视图/子图层时,请参考视图的bounds(当前视图内的坐标系),而不是framecenter(两者在superview的坐标系中);和
  4. 使用addSublayer 方法或layerClass 方法,但不能同时使用。

因此,添加CAShapeLayer 作为子层:

@IBDesignable
class CircleView: UIView {
    @IBInspectable var bubbleColor: UIColor = .blue { didSet { shapeLayer.fillColor = bubbleColor.cgColor } }

    private lazy var shapeLayer: CAShapeLayer = {
        let sLayer = CAShapeLayer()
        sLayer.fillColor = bubbleColor.cgColor
        return sLayer
    }()

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        shapeLayer.frame = bounds
        updatePath()
    }
}

// MARK: - Utility methods

private extension CircleView {
    func configure() {
        layer.addSublayer(shapeLayer)
    }

    func updatePath() {
        let diameter = min(bounds.width, bounds.height)
        let arcCenter = CGPoint(x: bounds.midX, y: bounds.midY)
        shapeLayer.path = UIBezierPath(arcCenter: arcCenter, radius: diameter / 2, startAngle: 0, endAngle: .pi * 2, clockwise: true).cgPath
    }
}

产量:


或者,如果你想使用layerClass 方法:

@IBDesignable
class CircleView: UIView {
    @IBInspectable var bubbleColor: UIColor = .blue { didSet { shapeLayer.fillColor = bubbleColor.cgColor } }

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

    private var shapeLayer: CAShapeLayer { return layer as! CAShapeLayer}

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        updatePath()
    }
}

// MARK: - Utility methods

private extension CircleView {
    func configure() {
        shapeLayer.fillColor = bubbleColor.cgColor
    }

    func updatePath() {
        let diameter = min(bounds.width, bounds.height)
        let arcCenter = CGPoint(x: bounds.midX, y: bounds.midY)
        shapeLayer.path = UIBezierPath(arcCenter: arcCenter, radius: diameter / 2, startAngle: 0, endAngle: .pi * 2, clockwise: true).cgPath
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多