SwiftUI:使用“ if else”更改视图

时间:2020-05-30 01:47:19

标签: swift xcode swiftui observable combine

我正在尝试根据通过按钮进行的​​选择来更改视图。我正在使用Combine和SwiftUI。

我使用@Published var创建一个视图路由器类:

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")
            }
        }
    }
}

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

var为@Published;它应该发布更改并更新主视图。

我错过了什么吗?

1 个答案:

答案 0 :(得分:3)

您有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())
}