ios - CALayer 自动布局

标签 ios swift calayer

我正在尝试创建 2 个层,它们相互堆叠并且位于自定义 View 类中。

图层的绘图效果很好,但我无法让它们根据使用自动布局设置的 View 位置调整它们的位置,其中 View 是在代码中创建的(无 IB)。

我尝试通过调用 layoutSubviews 来更改层的框架,这里是尝试的代码。

import UIKit

class ProgressView: UIView {

    let displayLayer:  CAShapeLayer = {
        let display = CAShapeLayer()
        display.strokeColor = UIColor.red.cgColor
        display.lineWidth = 8.0
        display.lineCap = CAShapeLayerLineCap.round
        display.fillColor = UIColor.clear.cgColor
        display.strokeEnd = 0.5

        return display
    }()

    let trackLayer: CAShapeLayer = {
        let track = CAShapeLayer()

        track.strokeColor = UIColor.lightGray.cgColor
        track.lineWidth = 6.0
        track.lineCap = CAShapeLayerLineCap.round
        track.fillColor = UIColor.clear.cgColor

        return track
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        let progressCircle = UIBezierPath(arcCenter: .zero, radius: 50, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)

        displayLayer.path = progressCircle.cgPath
        trackLayer.path = progressCircle.cgPath

        layer.addSublayer(trackLayer)
        layer.addSublayer(displayLayer)
    }

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

    override func layoutSubviews() {
        super.layoutSubviews()

        displayLayer.frame = bounds
        trackLayer.frame = bounds
    }
}

经过一些研究,我也尝试了 KVO 方法并使用了以下代码:

import UIKit

class ProgressView: UIView {
    let displayLayer:  CAShapeLayer = {
        let display = CAShapeLayer()

        display.strokeColor = UIColor.red.cgColor
        display.lineWidth = 8.0
        display.lineCap = CAShapeLayerLineCap.round
        display.fillColor = UIColor.clear.cgColor
        display.strokeEnd = 0.5

        return display
    }()

    let trackLayer: CAShapeLayer = {
        let track = CAShapeLayer()

        track.strokeColor = UIColor.lightGray.cgColor
        track.lineWidth = 6.0
        track.lineCap = CAShapeLayerLineCap.round
        track.fillColor = UIColor.clear.cgColor

        return track
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)

        let progressCircle = UIBezierPath(arcCenter: .zero, radius: 50, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)

        displayLayer.path = progressCircle.cgPath
        trackLayer.path = progressCircle.cgPath

        layer.addSublayer(trackLayer)
        layer.addSublayer(displayLayer)

        self.addObserver(self, forKeyPath: #keyPath(ProgressView.bounds), options: .new, context: nil)
    }

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

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == #keyPath(ProgressView.bounds) {
            displayLayer.frame = self.bounds
            trackLayer.frame = self.bounds
        }
    }
}

对于每个示例,我都会得到相同的结果,显示如下。请注意,紫色框是 ProgressView,我希望两层位于其中。

我一直在看这个,并认为我遗漏了一些简单的东西或做错了,我就是看不到它。

我在 observeValuelayoutSubviews 中都放置了 print 语句,以确保它们被调用并且有效。

这是我看到的: enter image description here

提前致谢。

最佳答案

您需要如下所示提供正确的 arcCenter,并且无需为 shapLayer 设置 frame

override func layoutSubviews() {
    super.layoutSubviews()

    let center = CGPoint(x: bounds.midX, y: bounds.midY)
    let progressCircle = UIBezierPath(arcCenter: center, radius: 50, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)

    displayLayer.path = progressCircle.cgPath
    trackLayer.path = progressCircle.cgPath
}

结果

enter image description here

注意:我使用了第一个没有KVOProgressView类。

关于ios - CALayer 自动布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53148356/

相关文章:

ios - PFQueryTableViewController 中附加了重复值

ios - 如何在 UITable 的不同部分中存储来自多行的多个文本字段值

ios - 在您的项目中找不到有效的 GoogleService-Info.plist

ios - 作为 MTKView subview 的 UIView 是否在 GPU 上处理/渲染?

ios - 最轻的 UI 元素

iOS,随机滑动动画

ios - 无法同时使用虚拟摇杆和 Remote

ios - 英雄过渡无效

objective-c - 在 forwar 类对象 CALayer 中找不到属性 anchorPoint

swift - 如何在 UIView 中为 TableView 标题部分绘制自定义形状?