繁体   English   中英

如何使用CAShapeLayer以编程方式快速在自定义UIView中居中绘制圆

[英]How to draw a circle using CAShapeLayer to be centered in a custom UIView in swift programmatically

我正在尝试使用CAShapeLayer在自定义约束的自定义UIView内绘制圆形进度条,我不想在超级视图的中心绘制圆,而是在自定义视图的中心绘制圆,因为我还有其他我上面的代码下面的视图会画一个圆,但是它不在指定的视图中

// 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 shapeLayer = CAShapeLayer()
        let centerForGauge = gaugeViewHolder.center

        let circularPath = UIBezierPath(arcCenter: centerForGauge
            , radius: 80, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)

        shapeLayer.path = circularPath.cgPath
        shapeLayer.strokeColor = UIColor.white.withAlphaComponent(0.20).cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = kCALineCapRound
        gaugeViewHolder.layer.addSublayer(shapeLayer)
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) {
    super.viewDidAppear(animated)

    let shapeLayer = CAShapeLayer()
    let centerForGauge = gaugeViewHolder.center
    print("gauge width:: \(centerForGauge)")
    let circularPath = UIBezierPath(arcCenter: CGPoint(x: gaugeViewHolder.frame.size.width/2, y: gaugeViewHolder.frame.size.height/2)
        , radius: 100, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)

    shapeLayer.path = circularPath.cgPath
    shapeLayer.strokeColor = UIColor.white.withAlphaComponent(0.50).cgColor
    shapeLayer.lineWidth = 10
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.lineCap = kCALineCapRound
    gaugeViewHolder.layer.addSublayer(shapeLayer)
}

如果您在设计时未自行设置框架,则可以考虑在将所有约束应用于视图之后再添加图层。 正如我在示例中测试的那样,这可以正常工作。

 var gaugeViewHolder : UIView!

     override func viewDidLoad() {
        super.viewDidLoad()
        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
}


  override func viewDidAppear(_ animated: Bool) {
                super.viewDidAppear(animated)
            let shapeLayer = CAShapeLayer()
            let centerForGauge = gaugeViewHolder.center
            let circularPath = UIBezierPath(arcCenter: centerForGauge
                , radius: 80, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)

            shapeLayer.path = circularPath.cgPath
            shapeLayer.strokeColor = UIColor.white.withAlphaComponent(0.20).cgColor
            shapeLayer.lineWidth = 10
            shapeLayer.fillColor = UIColor.clear.cgColor
            shapeLayer.lineCap = CAShapeLayerLineCap.round
            gaugeViewHolder.layer.addSublayer(shapeLayer)
        }

您永远不会设置形状图层的框架。 如果您希望形状图层覆盖视图的矩形,则它应该是拥有视图的边界。

这是将形状图层添加到我在示例应用程序情节提要中添加并作为IBOutlet连接的视图的代码:

@IBOutlet weak var gaugeViewHolder: UIView!

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    gaugeViewHolder.backgroundColor = UIColor.lightGray

    //Now my circle
    let shapeLayer = CAShapeLayer()
    shapeLayer.borderWidth = 2.0 //Add a box on the shape layer so you can see where it gets drawn.

    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 centerForGauge = gaugeViewHolder?.superview?.convert(gaugeViewHolder.center, to: gaugeViewHolder) ?? CGPoint.zero

    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 radius = max(shapeLayer.frame.size.width, shapeLayer.frame.size.height)/2.0 - lineWidth / 2.0

    let circularPath = UIBezierPath(arcCenter: centerForGauge
        , radius: radius, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)

    shapeLayer.path = circularPath.cgPath
    shapeLayer.strokeColor = UIColor.black.cgColor
    shapeLayer.lineWidth = lineWidth
    shapeLayer.fillColor = UIColor.yellow.cgColor
    shapeLayer.lineCap = .round
    gaugeViewHolder.layer.addSublayer(shapeLayer)
}

我更改了颜色和Alpha,并在shape图层上添加了borderWidth以使所有内容脱颖而出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM