【发布时间】:2021-04-15 19:23:33
【问题描述】:
我想为一个保存进度分数的 UIButton 设置动画, 这是第一个状态
我想将此按钮设置为最终状态
我使用 CAShapeLayer 来制作这些弧线和 我的代码是
let lineWidth: CGFloat = 12
let score = 90
let endAngle : CGFloat = .pi + (.pi * (CGFloat(score)/100))
let center = view.center
let progressPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: .pi, endAngle: endAngle, clockwise: true)
endPoint = progressPath.currentPoint
let startPoint: CGPoint = UIBezierPath(arcCenter: center, radius: 100, startAngle: .pi, endAngle: .pi, clockwise: true).currentPoint
let halfCirclePath = UIBezierPath(arcCenter: center, radius: 100, startAngle: .pi, endAngle: .pi*2, clockwise: true)
let greyLayer = CAShapeLayer()
greyLayer.strokeColor = greyColor
greyLayer.lineWidth = lineWidth
greyLayer.path = halfCirclePath.cgPath
greyLayer.lineCap = .round
greyLayer.fillColor = UIColor.clear.cgColor
greyLayer.shadowColor = UIColor.black.cgColor
greyLayer.shadowOpacity = 1
greyLayer.shadowOffset = .zero
greyLayer.shadowRadius = 2
view.layer.addSublayer(greyLayer)
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = lineWidth
shapeLayer.path = progressPath.cgPath
shapeLayer.lineCap = .round
shapeLayer.strokeEnd = 1
shapeLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(shapeLayer)
let label = UILabel()
label.text = "Best"
label.textAlignment = .center
label.textColor = .red
label.font = UIFont.boldSystemFont(ofSize: 30)
view.addSubview(label)
view.layer.addSublayer(label.layer)
label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
view.addSubview(scoreButton)
scoreButton.setTitle(" \(score)% ", for: .normal)
scoreButton.layer.masksToBounds = true
scoreButton.setTitleColor(.blue, for: .normal)
scoreButton.layer.shadowRadius = 8
scoreButton.layer.shadowColor = UIColor.black.cgColor
scoreButton.backgroundColor = .white
scoreButton.translatesAutoresizingMaskIntoConstraints = false
scoreButton.bottomAnchor.constraint(equalTo: view.topAnchor, constant: endPoint.y).isActive = true
scoreButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: endPoint.x).isActive = true
对于动画,我正在使用 DispatchQueu.main.asyncAfter 但无法更改 ScoreButton 的约束并且它不平滑
let frameCount:CGFloat = 100
for index in 0...Int(frameCount) {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(index)/Double(frameCount)) { [self] in
self.shapeLayer.strokeEnd = CGFloat(index )/frameCount
let currentPoint = UIBezierPath(arcCenter: center, radius: 100, startAngle: .pi, endAngle: .pi + (.pi * (CGFloat(index)/frameCount)), clockwise: true).currentPoint
self.scoreButton.bottomAnchor.constraint(equalTo: self.view.topAnchor, constant: currentPoint.y).isActive = true
self.scoreButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: currentPoint.x).isActive = true
self.view.layoutIfNeeded()
}
}
并且发生此错误
[5220:309329] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600000a20050 H:|-(114.789)-[UIButton:0x140905810' 90% '] (active, names: '|':UIView:0x140a06100 )>",
"<NSLayoutConstraint:0x600000a21270 H:|-(314)-[UIButton:0x140905810' 90% '] (active, names: '|':UIView:0x140a06100 )>"
)
有没有什么流畅的方法来为这个在动画进度中保存分数的 UIButton 设置动画?
【问题讨论】: