首页 > 解决方案 > SwiftUI 中两个嵌入式视图之间的过渡效果

问题描述

如果我有如下结构:

@State var currentView = "first"

VStack {
    if (state == "first") {
        View1()
    } else if (state == "second") {
        View2()
    } else {
        View3()
    }
}

还有一个 View1:

@Published var currentView: String

Button("to second") {
    currentView = "second"
}

更换时如何确保View2从左侧滑动View1?我可以动态定义下一个视图从哪一侧滑入吗?

标签: iosswiftswiftui

解决方案


  1. 您需要将动画附加到传递给视图的绑定
  2. 您的视图需要有一个@Binding属性,当点击按钮时它们会发生变化
  3. 然后您可以将过渡附加到您的视图,如果您使用,您可以控制过渡的边缘.move(定义视图从哪一侧滑入)

我让你的视图占据了整个屏幕并有颜色,这样过渡更明显。我还为每个过渡添加了持续时间,您可以修改或删除它。

import SwiftUI

struct ContentView: View {
    @State var currentView = "first"

    var body: some View {
        VStack {
            if (currentView == "first") {
                View1(currentView: $currentView.animation())
            } else if (currentView == "second") {
                View2(currentView: $currentView.animation())
            } else {
                View3(currentView: $currentView.animation())
            }
        }
    }

}

struct View1: View {

    @Binding var currentView: String

    var body: some View {
        ZStack {
            Rectangle().fill(Color.red)
            VStack {
                Text("View1")
                Button("to second") {
                    self.currentView = "second"
                }
            }

        }
        .transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
        .animation(.linear(duration: 2))

    }
}

struct View2: View {
    @Binding var currentView: String

    var body: some View {
        ZStack {
            Rectangle().fill(Color.yellow)
            VStack {
                Text("View2")
                Button("to third") {
                    self.currentView = "third"
                }
            }

        }
        .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
        .animation(.linear(duration: 2))

    }
}

struct View3: View {

    @Binding var currentView: String

    var body: some View {
        ZStack {
            Rectangle().fill(Color.pink)
            VStack {
                Text("View3")
                Button("to first") {
                    self.currentView = "first"
                }
            }

        }
        .transition(.asymmetric(insertion: .move(edge: .bottom), removal: .move(edge: .top)))
        .animation(.linear(duration: 2))
    }
}


推荐阅读