微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

创建具有程序约束的视图会导致在错误的位置绘制内容

如何解决创建具有程序约束的视图会导致在错误的位置绘制内容

我正在向另一个视图添加自定义视图,然后以编程方式设置其约束。这导致视图的内容绘制在错误的位置,我不确定为什么。这是我拥有的代码以及到目前为止我尝试过的代码

enter image description here

// Called in viewDidLoad
let buttonView = UIView()
buttonView.translatesAutoresizingMaskIntoConstraints = false

let ring = CircularProgressView()
ring.frame = CGRect(x: 0,y: 0,width: 80,height: 80)  
ring.backgroundColor = .yellow
    
buttonView.addSubview(ring)
self.view.addSubview(buttonView)


NSLayoutConstraint.activate([
    buttonView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor,constant: -12),buttonView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor,constant: -28),buttonView.heightAnchor.constraint(equalToConstant: 80),buttonView.widthAnchor.constraint(equalToConstant: 80),ring.centerXAnchor.constraint(equalTo: buttonView.centerXAnchor),ring.centerYAnchor.constraint(equalTo: buttonView.centerYAnchor)
])

我尝试调用ring.layoutIfNeeded()或使用约束设置环形视图的宽度和高度,但是它没有任何改变。

ring.heightAnchor.constraint(equalToConstant: 80),ring.widthAnchor.constraint(equalToConstant: 80)

CircleProgressView类如下所示。我尝试在此处使用边界而不是框架,或者不将值减2,然后再没有变化。

class CircularProgressView: UIView {

    // First create two layer properties
    private var circleLayer = CAShapeLayer()
    private var progressLayer = CAShapeLayer()
    private var currentValue: Double = 0

    override init(frame: CGRect) {
        super.init(frame: frame)
        createCircularPath()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createCircularPath()
    }


    func createCircularPath() {
        let circularPath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0,y: frame.size.height / 2.0),radius: 41,startAngle: -.pi / 2,endAngle: 3 * .pi / 2,clockwise: true)
        circleLayer.path = circularPath.cgPath
        circleLayer.fillColor = UIColor.clear.cgColor
        circleLayer.lineCap = .round
        circleLayer.linewidth = 3.0
        circleLayer.strokeColor = UIColor.black.withAlphaComponent(0.2).cgColor
        progressLayer.path = circularPath.cgPath
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.lineCap = .round
        progressLayer.linewidth = 3.0
        progressLayer.strokeEnd = 0
        progressLayer.strokeColor = UIColor.black.cgColor
        
        layer.addSublayer(circleLayer)
        layer.addSublayer(progressLayer)
        
        let circularProgressAnimation = CABasicAnimation(keyPath: "strokeEnd")
        circularProgressAnimation.duration = 2
        circularProgressAnimation.tovalue = 1
        circularProgressAnimation.fillMode = .forwards
        circularProgressAnimation.isRemovedOnCompletion = false
        progressLayer.add(circularProgressAnimation,forKey: "progressAnim")
        progressLayer.pauseAnimation()
    }
}

如果通过情节提要板进行操作,这一切都没有问题,但是我需要针对该用例以编程方式创建它,而我对问题所在感到困惑。

解决方法

您需要像编程一样制作两个视图

// Called in viewDidLoad
let buttonView = UIView()
buttonView.translatesAutoresizingMaskIntoConstraints = false

let ring = CircularProgressView()
ring.translatesAutoresizingMaskIntoConstraints = false 
ring.backgroundColor = .yellow
    
buttonView.addSubview(ring)
self.view.addSubview(buttonView)


NSLayoutConstraint.activate([
    buttonView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor,constant: -12),buttonView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor,constant: -28),buttonView.heightAnchor.constraint(equalToConstant: 80),buttonView.widthAnchor.constraint(equalToConstant: 80),ring.centerXAnchor.constraint(equalTo: buttonView.centerXAnchor),ring.centerYAnchor.constraint(equalTo: buttonView.centerYAnchor),ring.heightAnchor.constraint(equalToConstant: 80),ring.widthAnchor.constraint(equalToConstant: 80)
])

仅在createCircularPath内呼叫layoutSubviews

override func layoutSubviews() {
   super.layoutSubviews()
   createCircularPath()
}
,

还尝试将CircularProgressView的{​​{1}}属性设置为translatesAutoresizingMaskIntoConstraints

false

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。