How to draw a circle using CAShapeLayer to be centered in a custom UIView in swift programmatically
我正在尝试使用 CAShapeLayer 在已自动约束的自定义 UIView 中绘制圆形进度条,我不想在我的超级视图的中心绘制我的圆圈,而是在我的自定义视图的中心因为我在上面有其他视图,所以下面的代码绘制了一个圆圈,但它没有定位在指定的视图中
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Custom View
let gaugeViewHolder = UIView() scrollView.addSubview(gaugeViewHolder) gaugeViewHolder.translatesAutoresizingMaskIntoConstraints = false gaugeViewHolder.backgroundColor = UIColor.black gaugeViewHolder.leadingAnchor.constraint(equalTo: motherView.leadingAnchor).isActive = true gaugeViewHolder.topAnchor.constraint(equalTo: defaultAccImage.bottomAnchor, constant: 70).isActive = true gaugeViewHolder.trailingAnchor.constraint(equalTo: motherView.trailingAnchor).isActive = true gaugeViewHolder.heightAnchor.constraint(equalToConstant: 200).isActive = true //Now my circle let circularPath = UIBezierPath(arcCenter: centerForGauge shapeLayer.path = circularPath.cgPath |
- 您忘记设置 shapeLayer 的框架。
- @DuncanC 请问我该怎么做,因为我相信 shapeLayer.path = circularPath 可以做到这一点?
- 不,图层的路径和它的框架是完全相互独立的。框架是形状所在的相框。路径是在该框中绘制的几何形状。
- 我发布了一个带有工作代码的答案,显示了如何设置形状图层。关键是您需要设置 layer.frame = owningView.bounds,然后当您设置路径的中心时,它需要位于形状图层(或视图)的坐标系中。视图的 center 属性位于其父视图的坐标系中,这不是您想要的。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
let gaugeViewHolder = UIView()
override func viewDidLoad() { super.viewDidLoad() scrollView.addSubview(gaugeViewHolder) gaugeViewHolder.translatesAutoresizingMaskIntoConstraints = false gaugeViewHolder.backgroundColor = UIColor.black gaugeViewHolder.leadingAnchor.constraint(equalTo: motherView.leadingAnchor).isActive = true gaugeViewHolder.topAnchor.constraint(equalTo: defaultAccImage.bottomAnchor, constant: 70).isActive = true gaugeViewHolder.trailingAnchor.constraint(equalTo: motherView.trailingAnchor).isActive = true gaugeViewHolder.heightAnchor.constraint(equalToConstant: 200).isActive = true } override func viewDidAppear(_ animated: Bool) { let shapeLayer = CAShapeLayer() shapeLayer.path = circularPath.cgPath |
你永远不会设置形状图层的框架。如果您希望形状层覆盖视图的矩形,它应该是拥有视图的边界矩形。
以下代码将形状层添加到我在示例应用故事板中添加并连接为 IBOutlet 的视图中:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
@IBOutlet weak var gaugeViewHolder: UIView!
override func viewWillAppear(_ animated: Bool) { //Now my circle shapeLayer.frame = gaugeViewHolder.bounds //Use the view’s bounds as the layer’s frame //Convert gaugeViewHolder’s center from it’s superview’s coordinate system to it’s coordinate system let lineWidth = CGFloat(5.0) //Use 1/2 the shortest side of the shapeLayer’s frame for the radius, inset for the circle path’s thickness. let circularPath = UIBezierPath(arcCenter: centerForGauge shapeLayer.path = circularPath.cgPath |
我更改了周围的颜色和 alpha,并在形状图层中添加了一个边框宽度,以使所有内容都脱颖而出。
如果您没有在设计时自行设置框架,您可以考虑在所有约束都应用到您的视图之后再添加该层。正如我在一个示例中测试过的那样。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
var gaugeViewHolder : UIView!
override func viewDidLoad() {
override func viewDidAppear(_ animated: Bool) { shapeLayer.path = circularPath.cgPath |
- @E Coms您的解决方案有效,但问题是它不在gaugeViewHolder的中间,而是在它的下方。
- 你的代码很有帮助我需要做的是计算我的gaugeViewHolder的宽度并除以2同样适用于高度然后将它们分配给arcCenter。谢谢非常有帮助。我会尽快发布答案
- 你的代码很有帮助我需要做的是计算我的gaugeViewHolder的宽度并除以2同样适用于高度然后将它们分配给arcCenter。谢谢非常有帮助。我会尽快发布答案
- 很高兴听到这个消息。
来源:https://www.codenong.com/52795956/