从ViewRouter和ObservableObjects或environmentObject指向SwiftUI内部的所有三个视图

时间:2020-05-12 22:46:44

标签: swift view swiftui observableobject

我最近一直在使用SwiftUI,并且已经设法以ContentView.swift的rootView身份进行编写,其中包括2个按钮,可在应用程序中更改为其他“页面”或“屏幕”。目前,我可以在代码中的两个视图之间切换。我在每个“屏幕”快速文件中都使用了ObservableObjects(viewRouter:ViewRouter)。我决定编写第三个屏幕以弹出窗口供用户查看。在包括了显示该视图的相同结构和方式之后:第三视图的Button动作未运行。 编译没有错误,该应用将生成!但是,单击FirstScreen内的按钮时,ThirdScreen无法显示。

这是主视图ContentView:


import SwiftUI

struct ContentView: View {
    @State var screen: String = "FirstScreen" //Declares the first state
    @EnvironmentObject var viewRouter : ViewRouter //References our other swift file.

    var body : some View {
        VStack {
            if viewRouter.currentScreen == "FirstScreen" {
                FirstScreen()
                    } else if viewRouter.currentScreen == "SecondScreen" {
                SecondScreen()
                    .transition(.slide)
            } else if viewRouter.currentScreen == "ThirdScreen" {
                ThirdScreen()
                    .transition(.opacity)
            }
struct ContentView_Previews: PreviewProvider { //Looks fine, its the previews
    static var previews: some View {
        ContentView().environmentObject(ViewRouter())}}

这是FirstScreen文件,其结构如下:

import Foundation
import UIKit
import SwiftUI
struct FirstScreen : View {
    @EnvironmentObject var viewRouter : ViewRouter
    var body : some View {
    VStack {
    Button(action: {
            print("The info button has been clicked.")
        self.viewRouter.currentScreen = "SecondScreen" //Heres an action
           }) {
               Image(systemName: "info")
                   .padding()
                   .background(Color.green)
                   .font(.largeTitle)
                   .foregroundColor(Color.orange)
                   .frame(width: 300, height: 600)           
           }     
           Button(action: {
               print("You have erased it.")
            self.viewRouter.currentScreen = "ThirdScreen" //This action does not happen.
           }) {
               Image(systemName: "trash")
               .padding()
                   .background(Color.red)
                   .font(.largeTitle)
                   .foregroundColor(Color.white)
                   .frame(width: 426, height: 620)
}}}}
struct FirstScreen_previews : PreviewProvider {
    static var previews: some View {
        FirstScreen().environmentObject(ViewRouter())
    }
}

这是我的ThirdScreen的代码,应从ViewRouter加载该代码,并单击FirstScreen的Swift文件中的按钮进行更改。

import Foundation
import UIKit
import SwiftUI
struct ThirdScreen : View {
    @EnvironmentObject var viewRouter : ViewRouter
    var body : some View {
        VStack {
            Text("You step a bit off balance")
                .font(.largeTitle)
                .foregroundColor(Color.red)
            Text("You stand up, shaking, under a pass")
                .font(.callout)
            Text("It looks to be a wrong step. Maybe you head back?")
                .font(.caption)
                .foregroundColor(Color.gray)
            Button(action :{self.viewRouter.currentScreen = "FirstScreen"}){
                Image(systemName: "capslock" )
                    .frame(width: 209, height: 308)
                    .foregroundColor(Color.green)
}}}}
struct Third_preview : PreviewProvider {
    static var previews: some View {
        ThirdScreen().environmentObject(ViewRouter())
    }
}

这是ViewRouter.swift,可以很好地管理屏幕。

import Foundation
import Combine
import SwiftUI
class ViewRouter: ObservableObject {
    let objectWillChange = PassthroughSubject<ViewRouter, Never>()
    var currentScreen : String = "FirstScreen" {
        didSet {
            withAnimation(){
            objectWillChange.send(self)
        }
    }
}
}

最后,我正常工作的SecondScreen.swift。该文件可能是多余的,但我在偶然的机会将其包括在该文件中的情况下。由于按钮在内部起作用,因此可以更改视图。

import Foundation
import UIKit
import SwiftUI
struct SecondScreen : View {
    @EnvironmentObject var viewRouter : ViewRouter

    var body : some View {
    VStack { 
 Button(action: {self.viewRouter.currentScreen = "FirstScreen"}) {
            Image(systemName: "arrowshape.turn.up.left" )
            .padding()
            .cornerRadius(18)
                .frame(width: 180, height: 400)
}}}}
struct SecondScreen_previews : PreviewProvider{
    static var previews : some View {
        SecondScreen().environmentObject(ViewRouter())
    }
}

非常感谢您在这里为我提供的帮助。我希望继续制作屏幕文件,如下所示,我只是想知道为什么我的第三个屏幕没有拉起。在继续解决此问题时,我将迅速做出响应。谢谢!

1 个答案:

答案 0 :(得分:0)

!解决了使用其他按钮操作类型对代码进行的其他测试,并能够查看下一个屏幕。