ScrollView中的初始SwiftUI动画

时间:2020-07-18 14:22:49

标签: swiftui swiftui-animation

在我的应用中,我有一个ScrollView,其中包含一个VStackVStack有一个animation修饰符。它还具有一个带transition修饰符的条件视图。过渡有效。但是,当视图首次出现时,内容将以0的起始宽度按比例放大。您可以在下面的视频的绿色边框上看到此内容。仅当VStack位于ScrollView内或VStack具有animation修饰符的情况下。

我尝试了其他其他操作,例如设置fixedSize或设置animation(nil),但我无法使其正常工作。

我不在乎开头是否有动画,或者视图是否过渡到屏幕上。但我绝对不希望一开始就出现不良动画。当我单击按钮时,TextButton都应设置动画。

我还使用以下简化代码测试了此行为。

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        ScrollView {
            VStack(spacing: 32) {
                if self.viewModel.shouldShowText {
                    Text("Hello, World! This is a some text.")
                        .transition(
                            AnyTransition
                                .move(edge: .top)
                                .combined(
                                    with:
                                        .offset(
                                            .init(width: 0, height: -100)
                                        )
                                )
                        )
                }

                Button(
                    action: {
                        self.viewModel.didSelectButton()
                    },
                    label: {
                        Text("Button")
                            .font(.largeTitle)
                    }
                )
            }
            .border(Color.green)
            .animation(.easeInOut(duration: 5))
            .border(Color.red)

            HStack { Spacer() }
        }
        .border(Color.blue)
    }
}

class ViewModel: ObservableObject {
    @Published private var number: Int = 0

    var shouldShowText: Bool {
        return self.number % 2 == 0
    }

    func didSelectButton() {
        self.number += 1
    }
}

1 个答案:

答案 0 :(得分:2)

它在Xcode 12 / iOS 14(以及独立运行的NavigationView中)可以正常工作,因此我认为它是以前版本中的SwiftUI错误。

无论如何,请尝试通过如下所示的值激活动画(已测试并可行)

  // ... other code
}
.border(Color.green)
.animation(.easeInOut(duration: 5), value: viewModel.number)   // << here !!
.border(Color.red)

为此,它需要提供已发布的属性以供观察

class BlockViewModel: ObservableObject {
    @Published var number: Int = 0             // << here !!
 
    // ... other code