以编程方式为弧UIBezierPath设置约束

时间:2018-03-12 11:38:44

标签: ios swift autolayout calayer

我正在开发一个自定义循环进度条,但我不知道将它集中在所有设备的进度标签的同一中心。由于它是CAShapeLayer,我不能使用SnapKit手动添加约束,至少我不能通过代码执行,它没有约束属性。

如果我的故事板设置为iPhone 8,这是iPhone 8上的视图: enter image description here

这是iPhone X上使用相同故事板设置的视图: enter image description here

我的ViewController.swift

import UIKit

class ViewController: UIViewController {

    let trackLayer = CAShapeLayer()

    @IBOutlet weak var percentageLoadedLabel: UILabel!
    @IBOutlet weak var uiView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        createCircleProgressBar()
    }

    //MARK: Init track
    func createCircleProgressBar() {
        let center = percentageLoadedLabel.center

        let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi/2, endAngle: 3*CGFloat.pi/2, clockwise: true)

        trackLayer.path = circularPath.cgPath
        trackLayer.lineCap = kCALineCapRound
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.strokeColor = UIColor.lightGray.cgColor
        trackLayer.lineWidth = 10

        uiView.layer.addSublayer(trackLayer)
    }
}

它在其他设备上也有一些偏移量,但是当我将故事板更改为iPhone X时,它工作正常,仅适用于此设备,看起来行let center = percentageLoadedLabel.center获得故事板上设计的中心,在通过约束更新之前。

我尝试在故事板上添加UIView并在里面添加两个元素(UILabelCAShapeLayer)以获取中心属性,但它不起作用。

我正在努力奋斗这几天,我也尝试使用@IBDesignable来做,但我面临同样的问题。如果有人能帮助我,我感激不尽!

2 个答案:

答案 0 :(得分:2)

当你说:

时,你是对的
  

看起来行中心= percentageLoadedLabel.center获取故事板上设计的中心,然后由约束更新。

viewDidLoad中,您还不知道视图的正确大小,因此您不能依赖centerbounds frame等等

但是,方法viewDidLayoutSubviews(记录为here)。

正如它所说:

  

调用以通知视图控制器其视图刚刚布置了其子视图。

因此,如果我将您的电话转移至createCircleProgressBar()viewDidLayoutSubview(),请执行以下操作:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    createCircleProgressBar()
}

我在iPhone 8 plus上看到了这个

iPhone 8 plus

这是在iPhone X上

iPhone X

它在iPhone 8上看起来也不错:)

希望对你有所帮助。

答案 1 :(得分:1)

尝试将createCircleProgressBar()方法调用移至ViewDidAppear 问题是视图没有完全列在viewDidLoad()

您最好将此实现移至自定义视图,并将uiView类设置为故事板中的自定义视图类。

viewDidLayoutSubviews()

是获得视图中心的最佳位置。