我正在开发一个自定义循环进度条,但我不知道将它集中在所有设备的进度标签的同一中心。由于它是CAShapeLayer
,我不能使用SnapKit
手动添加约束,至少我不能通过代码执行,它没有约束属性。
如果我的故事板设置为iPhone 8,这是iPhone 8上的视图:
我的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
并在里面添加两个元素(UILabel
和CAShapeLayer
)以获取中心属性,但它不起作用。
我正在努力奋斗这几天,我也尝试使用@IBDesignable
来做,但我面临同样的问题。如果有人能帮助我,我感激不尽!
答案 0 :(得分:2)
当你说:
时,你是对的看起来行中心= percentageLoadedLabel.center获取故事板上设计的中心,然后由约束更新。
在viewDidLoad
中,您还不知道视图的正确大小,因此您不能依赖center
,bounds
frame
等等
但是,方法viewDidLayoutSubviews
(记录为here)。
正如它所说:
调用以通知视图控制器其视图刚刚布置了其子视图。
因此,如果我将您的电话转移至createCircleProgressBar()
至viewDidLayoutSubview()
,请执行以下操作:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
createCircleProgressBar()
}
我在iPhone 8 plus上看到了这个
这是在iPhone X上
它在iPhone 8上看起来也不错:)
希望对你有所帮助。
答案 1 :(得分:1)
尝试将createCircleProgressBar()
方法调用移至ViewDidAppear
问题是视图没有完全列在viewDidLoad()
您最好将此实现移至自定义视图,并将uiView
类设置为故事板中的自定义视图类。
viewDidLayoutSubviews()
是获得视图中心的最佳位置。