【发布时间】:2020-09-15 16:30:30
【问题描述】:
我已经构建了一个自定义的圆形范围选择器,类似于 iOS 的闹钟/就寝时间应用中的选择器。为了实现这一点,我使用了两个 UIButton thumbs 并附加了一个 UIPanGestureRecognizer 和一个 CAShapeLayer + UIBezierPath 指示它们之间的时间范围。当我使用触摸输入沿圆圈移动和调整圆弧本身的大小时,它的效果非常好。
请原谅我对圆圈的粗略描述,但这里是选择器工作原理的要点:
问题是我需要使用UISegmentedControl 在某些时间范围预设之间切换,我真的希望为这个更改设置动画。我已经使用CAKeyframeAnimation(keyPath: "position") 成功地为两个拇指(绿色) 沿着圆圈在所有 360 度上漂亮地设置了动画,但是我无法在我的时间范围内做到这一点(红色) CAShapeLayer。我管理的最好的方法是使用CABasicAnimation(keyPath: "path") 为范围层设置动画,但在动画过程中它发生了扭曲并且没有跟随圆弧,而是以直线矢量穿过圆。
为简洁起见,我将避免发布 getStuff() 函数的内容,因为它们与问题无关。
// This works
let startAngle: CGFloat = getAngle(for: start)
let startPath: UIBezierPath = getThumbTravelPath(fromAngle: startThumbAngle, toAngle: startAngle)
let startAnimation = CAKeyframeAnimation(keyPath: "position")
startAnimation.path = startPath.cgPath
startAnimation.isRemovedOnCompletion = false
startAnimation.calculationMode = .cubicPaced
startAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
startAnimation.duration = 0.2
startThumbView.layer.add(startAnimation, forKey: nil)
let endAngle: CGFloat = getAngle(for: end)
let endPath: UIBezierPath = getThumbTravelPath(fromAngle: endThumbAngle, toAngle: endAngle)
let endAnimation = CAKeyframeAnimation(keyPath: "position")
endAnimation.path = endPath.cgPath
endAnimation.isRemovedOnCompletion = false
endAnimation.calculationMode = .cubicPaced
endAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
endAnimation.duration = 0.2
endThumbView.layer.add(endAnimation, forKey: nil)
// This doesn't work
let path: UIBezierPath = getRangePathFor(startAngle: startAngle, endAngle: endAngle)
let pathAnimation = CABasicAnimation(keyPath: "path")
pathAnimation.fromValue = rangePath.cgPath
pathAnimation.toValue = path.cgPath
pathAnimation.duration = 0.2
pathAnimation.isRemovedOnCompletion = false
pathAnimation.isAdditive = true
rangeLayer.path = path.cgPath
rangeLayer.add(pathAnimation, forKey: nil)
我看到有人建议使用 CABasicAnimation(keyPath: "startStroke") + CABasicAnimation(keyPath: "endStroke") 方法,但据我所知,这行不通,因为我不能为 startStroke 设置负值,因此我不能有一个从 270° 延伸到 45° 的弧。
【问题讨论】:
-
为什么不从 270º 到 405º 设置动画?
-
问题是
startStroke&endStroke的范围只有0.0到1.0,这意味着我不能从0.75到1.125
标签: ios swift core-animation uibezierpath caanimation