【问题标题】:SwiftUI's AnimatableModifier is now deprecated, but how to "use Animatable directly"?SwiftUI 的 AnimatableModifier 现已弃用,但如何“直接使用 Animatable”?
【发布时间】:2022-01-21 17:13:49
【问题描述】:

我的目标是在偏移更改动画完成时实现回调。所以,我在网上找到了一个解决方法,它使用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 }
            }
        
    }
}

但事实证明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 }
            }
    }
}

感谢您的阅读,也许还有即将到来的答案!

【问题讨论】:

标签: ios animation swiftui deprecated


【解决方案1】:

请直接使用struct OffsetAnimation: Animatable, ViewModifier 而不是struct OffsetAnimation: AnimatableModifier

【讨论】:

  • 它对我也不起作用。如果我直接使用 AnimatableModifier 则动画有效。如果我使用 Animatable、ViewModifier 进行调整,那么动画将不起作用。
猜你喜欢
  • 1970-01-01
  • 2010-12-04
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 2022-09-27
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多