Gwo*_*ozi 14 animation deprecated ios swiftui
我的目标是在偏移更改动画完成时实现回调。因此,我在网上找到了一种解决方法,它使用 来AnimatableModifier检查何时animatableData等于目标值。
struct OffsetAnimation: AnimatableModifier{
typealias T = CGFloat
var animatableData: T{
get { value }
set {
value = newValue
print("animating \(value)")
if watchForCompletion && value == targetValue {
DispatchQueue.main.async { [self] in onCompletion() }
}
}
}
var watchForCompletion: Bool
var value: T
var targetValue: T
init(value: T, watchForCompletion: Bool, onCompletion: @escaping()->()){
self.targetValue = value
self.value = value
self.watchForCompletion = watchForCompletion
self.onCompletion = onCompletion
}
var onCompletion: () -> ()
func body(content: Content) -> some View {
return content.offset(x: 0, y: value).animation(nil)
}
}
struct DemoView: View {
@State var offsetY: CGFloat = .zero
var body: some View {
Rectangle().frame(width: 100, height: 100, alignment: .center)
.modifier(
OffsetAnimation(value: offsetY,
watchForCompletion: true,
onCompletion: {print("translation complete")}))
.onAppear{
withAnimation{ offsetY = 100 }
}
}
}
Run Code Online (Sandbox Code Playgroud)
但事实证明AnimatableModifier现在已被弃用。我找不到替代方案。
我知道这GeometryEffect适用于这种偏移量更改的情况,您可以用它ProjectionTransform来实现这一点。但我更关心官方推荐的“直接使用Animatable”。
Animatable说真的,我可以在网上找到的有关该协议的教程都使用Shape隐式实现该协议的结构Animatable的示例。我用协议即兴创作的以下代码Animatable甚至没有执行“动画”。
struct RectView: View, Animatable{
typealias T = CGFloat
var animatableData: T{
get { value }
set {
value = newValue
print("animating \(value)")
}
}
var value: T
var body: some View{
Rectangle().frame(width: 100, height: 100, alignment: .center)
.offset(y:value).animation(nil)
}
}
struct DemoView: View{
@State var offsetY: CGFloat = .zero
var body: some View {
RectView(value: offsetY)
.onAppear{
withAnimation{ offsetY = 100 }
}
}
}
Run Code Online (Sandbox Code Playgroud)
感谢您的耐心阅读,也许还有即将到来的答案!
请在 iOS 15 及以上struct OffsetAnimationView: View, Animatable版本struct OffsetAnimation: AnimatableModifier中直接使用。
在iOS 15及以上版本中,我只使用继承andAnimatable来实现动画,没有使用or 。然而,在15以下的iOS版本中,我必须使用然后使用来应用它。对于应用程序中的每个动画,我使用这两种方法编写了两次。ViewAnimatableViewModifierAnimatableModifierAnimatableModifierColor.clear.modifier(...)
例如:
struct FooAnimatableModifier: AnimatableModifier {
let oldValue: Int
let newValue: Int
var pct: CGFloat
var animatableData: CGFloat {
get { pct }
set { pct = newValue }
}
var currentValue: CGFloat {
CGFloat(oldValue) + (CGFloat(newValue) - CGFloat(oldValue)) * pct
}
func body(content: Content) -> some View {
FooStaticView(value: currentValue)
}
}
struct FooAnimatableView: View, Animatable {
let oldValue: Int
let newValue: Int
var pct: CGFloat
var animatableData: CGFloat {
get { pct }
set { pct = newValue }
}
var currentValue: CGFloat {
CGFloat(oldValue) + (CGFloat(newValue) - CGFloat(oldValue)) * pct
}
var body: some View {
FooStaticView(value: currentValue)
}
}
struct FooStaticView: View {
var value: CGFloat
var body: some View {
Text("\(value)")
}
}
struct FooView: View {
@State var isAnimated = false
var body: some View {
Group {
if #available(iOS 15, *) {
FooAnimatableView(oldValue: 20, newValue: 80, pct: isAnimated ? 1 : 0)
} else {
EmptyView().modifier(
FooAnimatableModifier(oldValue: 20, newValue: 80, pct: isAnimated ? 1 : 0)
)
}
}
.animation(.linear(duration: 0.5), value: isAnimated)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
isAnimated = true
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
避免在 iOS 13.2 以下的容器(例如 VStack)中使用它。
| 归档时间: |
|
| 查看次数: |
2302 次 |
| 最近记录: |