iOS 是否有等效的 FastOutSlowInInterpolator?
Is there an equivalent of FastOutSlowInInterpolator for iOS?
是否也有 FastOutSlowInInterpolator for iOS? I've recently got my hands on AndroidX and really like this interpolator. I've found the source code 的等价物,但不知道如何将其转换为 iOS 实现。
如果您正在使用 UIViewPropertyAnimator
,则您需要的曲线是 .easeInOut,您可以在创建动画器时将其作为 curve
参数传递:
let animator = UIViewPropertyAnimator(duration: 0.4, curve: .easeInOut) {
// Animations
}
如果对这个系统曲线不满意,可以按照this answer and use this handy website复制FastOutSlowInInterpolator
的控制点
如 FastOutSlowInInterpolator 文档所述:
Interpolator corresponding to fast_out_slow_in
. Uses a lookup table
for the Bezier curve from (0,0) to (1,1) with control points: P0 (0,
0) P1 (0.4, 0) P2 (0.2, 1.0) P3 (1.0, 1.0)
因此,在您的特定情况下,您正在寻找这样的东西:
let timingParameters = UICubicTimingParameters(
controlPoint1: CGPoint(x: 0.4, y: 0),
controlPoint2: CGPoint(x: 0.2, y: 1)
)
let animator = UIViewPropertyAnimator(duration: 0.4, timingParameters: timingParameters)
或者这个:
let animator = UIViewPropertyAnimator(
duration: 0.4,
controlPoint1: CGPoint(x: 0.4, y: 0),
controlPoint2: CGPoint(x: 0.2, y: 1)
) {
// Animations
}
SwiftUI
在 SwiftUI 中,您可以使用 .animate
修饰符为几乎任何变化设置动画,并且它接受曲线作为参数。我认为 .interpolatingSpring(stiffness: 30, damping: 20)
是您正在寻找的曲线(底部)。
例子
struct ContentView: View {
@State var isLeading = false
var body: some View {
VStack {
SpacedCircle(isLeading: $isLeading)
.animation(.linear)
SpacedCircle(isLeading: $isLeading)
.animation(.easeIn)
SpacedCircle(isLeading: $isLeading)
.animation(.easeOut)
SpacedCircle(isLeading: $isLeading)
.animation(.easeInOut)
SpacedCircle(isLeading: $isLeading)
.animation(.interactiveSpring(response: 0.27, dampingFraction: 0.5, blendDuration: 0.2))
SpacedCircle(isLeading: $isLeading)
.animation(.interpolatingSpring(stiffness: 30, damping: 20))
Button("Toggle") { isLeading.toggle() }
}
}
}
UIKit
您也可以在 UIKit 中实现类似的功能:
例子
@IBAction func touched(_ sender: UIButton) {
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
self.circleView.transform = .identity
}
}
@IBAction func touchDown(_ sender: Any) {
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
self.circleView.transform = CGAffineTransform(translationX: 240, y: 0)
}
}
是否也有 FastOutSlowInInterpolator for iOS? I've recently got my hands on AndroidX and really like this interpolator. I've found the source code 的等价物,但不知道如何将其转换为 iOS 实现。
如果您正在使用 UIViewPropertyAnimator
,则您需要的曲线是 .easeInOut,您可以在创建动画器时将其作为 curve
参数传递:
let animator = UIViewPropertyAnimator(duration: 0.4, curve: .easeInOut) {
// Animations
}
如果对这个系统曲线不满意,可以按照this answer and use this handy website复制FastOutSlowInInterpolator
的控制点
如 FastOutSlowInInterpolator 文档所述:
Interpolator corresponding to
fast_out_slow_in
. Uses a lookup table for the Bezier curve from (0,0) to (1,1) with control points: P0 (0, 0) P1 (0.4, 0) P2 (0.2, 1.0) P3 (1.0, 1.0)
因此,在您的特定情况下,您正在寻找这样的东西:
let timingParameters = UICubicTimingParameters(
controlPoint1: CGPoint(x: 0.4, y: 0),
controlPoint2: CGPoint(x: 0.2, y: 1)
)
let animator = UIViewPropertyAnimator(duration: 0.4, timingParameters: timingParameters)
或者这个:
let animator = UIViewPropertyAnimator(
duration: 0.4,
controlPoint1: CGPoint(x: 0.4, y: 0),
controlPoint2: CGPoint(x: 0.2, y: 1)
) {
// Animations
}
SwiftUI
在 SwiftUI 中,您可以使用 .animate
修饰符为几乎任何变化设置动画,并且它接受曲线作为参数。我认为 .interpolatingSpring(stiffness: 30, damping: 20)
是您正在寻找的曲线(底部)。
例子
struct ContentView: View {
@State var isLeading = false
var body: some View {
VStack {
SpacedCircle(isLeading: $isLeading)
.animation(.linear)
SpacedCircle(isLeading: $isLeading)
.animation(.easeIn)
SpacedCircle(isLeading: $isLeading)
.animation(.easeOut)
SpacedCircle(isLeading: $isLeading)
.animation(.easeInOut)
SpacedCircle(isLeading: $isLeading)
.animation(.interactiveSpring(response: 0.27, dampingFraction: 0.5, blendDuration: 0.2))
SpacedCircle(isLeading: $isLeading)
.animation(.interpolatingSpring(stiffness: 30, damping: 20))
Button("Toggle") { isLeading.toggle() }
}
}
}
UIKit
您也可以在 UIKit 中实现类似的功能:
例子
@IBAction func touched(_ sender: UIButton) {
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
self.circleView.transform = .identity
}
}
@IBAction func touchDown(_ sender: Any) {
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
self.circleView.transform = CGAffineTransform(translationX: 240, y: 0)
}
}