SwiftUI:使用 "if else" 更改视图

SwiftUI: changing view using "if else"

我正在尝试根据使用按钮所做的选择来更改视图。我正在使用 Combine 和 SwiftUI。

我用 @Published var:

创建了一个视图路由器 class
import Foundation
import SwiftUI
import Combine

class ViewRouter: ObservableObject {

    @Published var currentView = "folder"

}

我有我的按钮结构:

import SwiftUI
import Combine

struct MultiButton: View {
    @ObservedObject var viewRouter = ViewRouter()
    @State var showButton = false

    var body: some View {
        GeometryReader { geometry in
            ZStack{

                // open multi button
                Button(action: {

                    withAnimation {
                        self.showButton.toggle()
                    }
                }) {
                    Image(systemName: "gear")
                        .resizable()
                        .frame(width: 40, height: 40, alignment: .center)
                }
                if self.showButton {

                    Multi()
                    .offset(CGSize(width: -30, height: -100))
                }
            }


        }
    }
}

struct MultiButton_Previews: PreviewProvider {
    static var previews: some View {
        MultiButton()
    }
}

struct Multi: View {

 @ObservedObject var viewRouter = ViewRouter()

    var body: some View {
        HStack(spacing: 10) {
            ZStack {

                Button(action: {
                    self.viewRouter.currentView = "folder"
                     debugPrint("\(self.viewRouter.currentView)")
                }) {
                    ZStack{

                    Circle()
                        .foregroundColor(Color.blue)
                        .frame(width: 70, height: 70)
                    Image(systemName: "folder")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(20)
                        .frame(width: 70, height: 70)
                        .foregroundColor(.white)
                    }.shadow(radius: 10)
                }
            }

            Button(action: {
                self.viewRouter.currentView = "setting"
                debugPrint("\(self.viewRouter.currentView)")
            }, label: {
                ZStack {
                    Circle()
                        .foregroundColor(Color.blue)
                        .frame(width: 70, height: 70)
                    Image(systemName: "gear")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(20)
                        .frame(width: 70, height: 70)
                        .foregroundColor(.white)
                }.shadow(radius: 10)
            })
        }
            .transition(.scale)
    }
}

contentView:

import SwiftUI
import Combine

struct ContentView: View {
    @ObservedObject var viewRouter = ViewRouter()
    var body: some View {
        VStack{

            MultiButton()

            if viewRouter.currentView == "folder" {
                Text("folder")
            } else if viewRouter.currentView == "setting"{
                Text("setting")
            }
        }
    }
}

为什么按下按钮时我的文本没有从文件夹更改为设置基础?

变量是@Published;它应该发布更改并更新主视图。

我是不是漏掉了什么?

您有多个 ViewRouter 实例,每个视图都有自己的实例。如果您更改该实例,其他实例将不会更改。

要解决这个问题,您要么必须手动传递一个实例:

struct MultiButton {
    @ObservedObject var viewRouter: ViewRouter
    ...
}

struct ContentView {
    @ObservedObject var viewRouter = ViewRouter()
    var body: some View {
        VStack {
            MultiButton(viewRouter: self.viewRouter)
            ...
        }
    }
}

或者您可以将其声明为环境对象:

struct MultiButton {
    @EnvironmentObject var viewRouter: ViewRouter
    ...
}

然后在场景委托中创建视图层次结构时注入它:

let contentView = ContentView()
    .environmentObject(ViewRouter())

请注意,在场景委托中注入环境对象时,它不会在使用 ViewRouter 的视图的每个预览中都可用,除非您也在那里手动注入它:

static var previews: some View {
    ContentView()
    .environmentObject(ViewRouter())
}