簡體   English   中英

iOS:在受約束的子視圖中居中 CAShapeLayer

[英]iOS: centering CAShapeLayer inside a constrained subview

我正在嘗試在 Circle 的中心渲染一個形狀,這是 UIView 的自定義子類(第一個片段)。 然后我將 Circle 添加為我的 VC 中的子視圖並添加約束(第二個片段)。

當高度和寬度受到約束時,渲染形狀的中心(不希望出現)在圓形視圖的左上角(如下圖)。 當僅約束圓形視圖的 X 和 Y 時,形狀按預期位於中心。

為什么會發生這種情況,我該怎么做才能隨意約束圓形,但形狀仍呈現在圓形的中心? 謝謝。

圓圈:

class Circle: UIView {

func render(){
    let shapeLayer = CAShapeLayer()
    let center = self.center
    let endAngle = 2 * CGFloat.pi
    let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: 0, endAngle: endAngle, clockwise: true)

    shapeLayer.path = circularPath.cgPath
    self.layer.addSublayer(shapeLayer)
  }
}

風險投資:

class VC: UIViewController {
let circle = Circle()

override func viewDidLoad() {
    super.viewDidLoad()        
    configure()
    circle.render()
}

func configure(){
    view.backgroundColor = .white
    view.addSubview(progressCircle)
    progressCircle.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        progressCircle.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        progressCircle.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        progressCircle.heightAnchor.constraint(equalToConstant: 200),
        progressCircle.widthAnchor.constraint(equalToConstant: 200)
    ])
  }
}

結果:

結果

這是固定視圖(使用 Xcode 11.4 / Playground 測試)

class Circle: UIView {
    let shapeLayer = CAShapeLayer()

override func layoutSubviews() {
    super.layoutSubviews()
    shapeLayer.position = CGPoint(x: self.bounds.midX, y: self.bounds.midY)
}

func render(){
    let center = self.center
    let endAngle = 2 * CGFloat.pi
    let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: 0, endAngle: endAngle, clockwise: true)

    shapeLayer.path = circularPath.cgPath
    self.layer.addSublayer(shapeLayer)
  }
}

以下面的解決方案結束(這次不同的形狀,但原理適用)。 按預期工作,現在可以根據需要在 VC 中限制和移動視圖。

class Circle: UIView {

private var layer: CAShapeLayer!
override func draw(_ rect: CGRect) {

    let width =  rect.width
    let height = rect.height        
    let lineWidth = 0.1 * min(width, height)
    let center = CGPoint(x: width / 2, y: height / 2)
    let radius = (min(width, height) - lineWidth) / 2
    let startAngle = -CGFloat.pi / 2
    let endAngle = startAngle + 2 * CGFloat.pi
    let circularPath = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)

    layer = CAShapeLayer()
    layer.path = circularPath.cgPath
    layer.strokeColor = UIColor.lightGray.cgColor
    layer.lineWidth = lineWidth
    layer.fillColor = UIColor.clear.cgColor
    layer.lineCap = .round

    layer.addSublayer(backbroundLayer)

  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM