0

I have been using SwiftUI lately, and I have managed to write in ContentView.swift as my rootView, including 2 buttons to change to other "pages" or "screens" within an app. Currently, I am able to move between Two views in my code. I used ObservableObjects(viewRouter : ViewRouter) in each "screen" swift file. I decided to write a third screen to pop up for a user to view. After including the same structures and ways to bring up that view : The Button's Action for the third view is not being ran. There are no errors in compiling, the app will build! But, the ThirdScreen is not visible when clicking the button inside FirstScreen.

Here is the Main View 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())}}

Here is the FirstScreen file with its structure below:

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

Here is the code for my ThirdScreen which should be loaded in from ViewRouter and the change from clicking the button from the FirstScreen's Swift file.

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

Here is the ViewRouter.swift which works fine to manage screens.

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

Lastly, my correctly working SecondScreen.swift. This file is probably redundant, but I included it on the off chance that something good is working inside this file. As buttons work inside to change views.

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

Thank you extremely for helping me here. I would love to continue making Screen files as the they are below, I just wonder why my third screen isn't pulled up. I will be responding quickly as I continue to troubleshoot this. Thank you!

  • Works fine. Tested with Xcode 11.4. Have you test it in Simulator or Preview? – Asperi May 13 '20 at 03:57
  • @Asperi Were you able to click the red icon in simulator and view the ThirdScreen view? I was having an issue viewing it, as my code also ran and built itself, however the button function did not go through using simulator. – Tomato_code May 14 '20 at 07:14

1 Answers1

0

!solved Ran a few more tests on the code using other action types for buttons, and was able to view the next screen.