Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/121.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在IOS中跨圆弧设置视图约束动画_Ios_Swift_Animation - Fatal编程技术网

在IOS中跨圆弧设置视图约束动画

在IOS中跨圆弧设置视图约束动画,ios,swift,animation,Ios,Swift,Animation,我想制作一个保存进度分数的UIButton动画, 这是第一个州 我想把这个按钮动画到最后的状态 我用CAShapeLayer做了这些弧 我的代码是 let lineWidth: CGFloat = 12 let score = 90 let endAngle : CGFloat = .pi + (.pi * (CGFloat(score)/100)) let center = view.center let prog

我想制作一个保存进度分数的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 )>"
)
[5220:309329][LayoutConstraints]无法同时满足约束。
可能下面列表中至少有一个约束是您不想要的。
试试这个:
(1) 看看每一个约束,试着找出你不期望的;
(2) 找到添加了不需要的约束的代码,然后修复它。
(
"",
""
)

是否有任何平滑的方式来设置此UIButton的动画,该按钮在动画过程中保留分数?

您可以在此处设置约束

  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
在这里创建另一个C冲突

 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
您需要先停用旧的,然后再添加新的,或者仅像这样更改常量

var bottomCon,leadingCon:NSLayoutConstraint?



沿弯曲路径设置视图/层动画的关键是使用关键帧动画。UIView和CALayer都支持关键帧动画

在您的情况下,应该能够使用视图水平和垂直约束的偏移常量的UIView动画

您应该能够在线找到有关使用UIView关键帧动画沿弯曲路径设置视图动画的教程

为圆弧设置动画将需要创建一个CABASICANIATION来为CAShapeLayer的strokeEnd属性设置动画。同样,网上也有关于如何做到这一点的各种教程。(我最近写了一篇关于使用这种技术制作复选标记动画的SO帖子。)

Tnx:),它工作得很好,但并不平滑,有没有任何功能来制作动画和监控进度?
  scoreButton.translatesAutoresizingMaskIntoConstraints = false

  bottomCon = scoreButton.bottomAnchor.constraint(equalTo: view.topAnchor, constant: endPoint.y)
  bottomCon.isActive = true

  leadingCon = scoreButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: endPoint.x) 
  leadingCon.isActive = true
 self.bottomCon.constant = currentPoint.y 
 self.leadingCon.constant = currentPoint.x 
 UIView.animate(withDuration: 0.3) {
    self.view.layoutIfNeeded()
 }