条件子视图的SwiftUI过渡

时间:2020-02-14 17:24:32

标签: swiftui swiftui-animation

我正在尝试理解和试验swiftUI视图转换,并且可以对以下原因为何无法按我期望的方式进行了解:

struct ContentView: View {
@State private var showOverlay: Bool = false

var body: some View {
    ZStack {
        VStack {
            Button(action: {
                withAnimation(.easeInOut) {
                    self.showOverlay = true
                }
            }) {
                Text("Hello, World!")
            }
        }
        .zIndex(0)
        .animation(nil)
        .blur(radius: showOverlay ? 3 : 0)

        if showOverlay {
            HStack {
                Button(action: {
                    withAnimation(.easeInOut) {
                        self.showOverlay = false
                    }
                }) {
                    Text("Close")
                }
                .frame(width: 80, height: 80)
                .background(Color.red)
                .transition(.move(edge: .top))

                Button(action: {
                    withAnimation(.easeInOut) {
                        self.showOverlay = false
                    }
                }) {
                    Text("Close")
                }
                .frame(width: 80, height: 80)
                .background(Color.red)
                .transition(.move(edge: .bottom))
            }
            .zIndex(1.0)
        }
    }
}

有条件的HStack中有两个按钮。 更改@State参数showOverlay时,它将在withAnimation块内完成。 各个按钮上的过渡均不适用。

如果我删除HStack,并将zIndex(1)放在每个按钮上,则会发生删除过渡,但不会发生插入过渡。

当它们的组添加到视图中时,我希望两个按钮以其指定的方式转换。

问题: 为什么在HStack中包装会导致内部转换被忽略? 为什么边缘过渡仅在1个方向上起作用?

2 个答案:

答案 0 :(得分:1)

转换适用于显示/消失的视图。在提供的代码快照中,快照{/ {1}}出现/消失,因此应对其进行过渡。

注意:转换必须在Simulator或真实设备上进行测试,其中大多数都不能在Preview中使用。

下面是代码的经过修改的部分,可提供有效的行为。经过Xcode 11.2 / iOS 13.2的测试

enter image description here

HStack

答案 1 :(得分:0)

为了获得两种不同的动画,您可以将条件逻辑拉近按钮,即在HStack内部:

HStack {
  if showOverlay {
    Button(action: {
      withAnimation(.easeInOut) {
        self.showOverlay = false
      }
    }) {
      Text("Close")
    }
    .frame(width: 80, height: 80)
    .background(Color.red)
    .transition(.move(edge: .top))

    Button(action: {
      withAnimation(.easeInOut) {
        self.showOverlay = false
      }
    }) {
      Text("Close")
    }
    .frame(width: 80, height: 80)
    .background(Color.red)
    .transition(.move(edge: .bottom))
  }
}
.zIndex(1.0)

HStack时,这会给您一个空的showOverlay == false,但这并不是什么大问题,至少在此示例中如此。