【问题标题】:SwiftUI animation with switch statement带有 switch 语句的 SwiftUI 动画
【发布时间】:2021-02-19 01:10:43
【问题描述】:

我了解简单动画在 SwiftUI 中的工作原理。但是,我有一个稍微复杂的 watchOS 应用程序。视图状态由switch 语句处理:

struct ContentView: View {
    @EnvironmentObject private var state: AppState

    @State private var selection = 1

    var body: some View {
        Group {
            switch state.view {
            case .start:
                TabView(selection: $selection) {
                    ActivityView()
                        .tag(0)
                    StartView()
                        .tag(1)
                    SettingsView()
                        .tag(2)
                }
            case .workout:
                TabView(selection: $selection) {
                    TakeoffControlView()
                        .tag(0)
                    TakeoffView()
                        .tag(1)
                }
            }

            // ...
        }
    }
}

在另一个视图中我编辑视图状态:

struct StartView: View {
    @EnvironmentObject private var state: AppState

    var body: some View {
        Button(action: {
            state.view = .workout
        }, label: {
            Text("Start")
        })
    }
}

如何添加动画以在不同情况之间进行转换?我尝试向GroupTabView 和单个视图添加动画但没有成功。显然我在withAnimation 中包装了状态更改。但是,我无法使其工作。任何想法如何使这项工作?

【问题讨论】:

  • 如果可能,请添加可重现的代码!

标签: ios swift swiftui watchos


【解决方案1】:

.transition() 只是定义什么是过渡,要获得预期的过渡动画,您必须在 withAnimation() { ... } 块内对 SourceOfTruth 进行更改。

struct ContentView: View {
    @EnvironmentObject private var state: AppState

    @State private var selection = 1

    var body: some View {
        Group {
            switch state.view {
            case .start:
                TabView(selection: $selection) {
                    ActivityView()
                        .tag(0)
                    StartView()
                        .tag(1)
                    SettingsView()
                        .tag(2)
                }
                .transition(.slide)//<- here
                
            case .workout:
                TabView(selection: $selection) {
                    TakeoffControlView()
                        .tag(0)
                    TakeoffView()
                        .tag(1)
                }
                .transition(.slide)//<- here
            }

            // ...
        }
    }
}

struct StartView: View {
    @EnvironmentObject private var state: AppState

    var body: some View {
        Button(action: {
            withAnimation(.easeIn) {  //<- here
                state.view = .workout
            }
        }, label: {
            Text("Start")
        })
    }
}

【讨论】:

  • 但是你不能总是把你的动作逻辑放在Button 闭包中。有时state.view = .workout 会出现在视图模型等内部。如果您可以将转换逻辑放在 switch 语句附近,那就太好了。
  • @flopshot 如果你在你的虚拟机中添加 withAnimation 它仍然可以工作。
  • 非常感谢!正是我想要的。任何认为这不起作用的提示:您必须在模拟器中运行它,显然动画不适用于实时预览
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
  • 2018-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多