这个SwiftUI动画只能淡出。为什么它会向右移动?

时间:2019-06-20 06:15:38

标签: swift swiftui

我很难理解为什么会这样。我将问题简化为最小表达。

我只有一个Text视图,将其删除后应淡出。 .transition(.opacity)被添加只是为了清楚。不需要它,因为它是默认值。但是,结果是,除了淡入淡出之外,文本视图还向右滑动。

通过播放文本长度,我意识到在过渡期间,其左边界要与 CHANGE (更改)按钮的左边界对齐。但是为什么?!

相反,当加回去时,它工作正常并且没有运动。只是一个不错的淡入效果。

问题不仅发生在iOS上,而且发生在macOS上。使用Xcode 11 beta 2。

enter image description here

import SwiftUI

struct ContentView : View {
    @State private var showText = true

    var body: some View {
        VStack {

            Spacer()

            if showText {
                Text("I should always be centered!").font(.largeTitle).transition(.opacity)
            }

            Spacer()

            Button(action: {
                withAnimation(.basic(duration: 1.5)) { self.showText.toggle() }
            }, label: {
                Text("CHANGE").font(.title)
            })

            Spacer()

            }
    }
}

3 个答案:

答案 0 :(得分:6)

我将回答我自己的问题...事实证明,父视图在过渡期间会缩小,从而使文本视图随其移动。为了说明,我在视图中添加了一些边框:

enter image description here

为了解决该问题,我必须确保父视图不会缩小。只需添加以下内容即可:

HStack { Spacer() }

enter image description here

修改后的代码如下:

import SwiftUI

struct ContentView : View {
    @State private var showText = true

    var body: some View {
        VStack {
            Spacer()

            if showText {
                Text("I should always be centered!").font(.largeTitle).transition(.opacity).border(Color.blue)
            }

            Spacer()

            Button(action: {
                withAnimation(.basic(duration: 1.5)) { self.showText.toggle() }
            }, label: {
                Text("CHANGE").font(.title).border(Color.blue)
            })

            Spacer()

            // This ensures the parent is kept wide to avoid the shift
            HStack { Spacer() }

        }.border(Color.green)
    }
}

我仍然认为这是一个错误,否则淡入应该具有相同的行为,而事实并非如此。如果这不是一个bug,那不是人们所期望的。我将提交错误报告。

答案 1 :(得分:3)

SwiftUI会自动为布局更改设置动画。

我的理论是,Spacer会在隐藏时替换Text,并且通过扩展以填充超级视图,它将Text推向屏幕的后沿。

您可以使用此方法解决此问题:

Text("I should always be centered!")
                .font(.largeTitle)
                .opacity(showText ? 1 : 0)

Text将淡入/淡出而不会移动。

答案 2 :(得分:0)

对我来说,我通过简单添加以下修饰符解决了该问题:

.transition(.identity)
.animation(nil)

这停止了SwiftUI自动创建的任何默认动画。