Как я могу показать страницу в зависимости от дочерней кнопки, нажатой с помощью SwiftUI? - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь переписать свое приложение, используя только SwiftUI, и у меня возникают трудности с EnvironmentObject, я пытаюсь понять, как он работает…

Я хочу перенаправить пользователей моего приложения на соответствующую страницу при запуске, в зависимости от на:

  • , если это их первый раз
  • , если у них есть логин,
  • , если они хотят начать использовать без входа

Если приложение запускается впервые, у LocalStorage нет данных, поэтому я представляю приложение на странице приветствия. Я предлагаю на выбор 2 кнопки для нажатия:

  • «Новый пользователь» которые перенаправляют на главную страницу приложения и создают нового пользователя
  • «Вход», который представляет страницу входа для получения последней резервной копии. Если приложение было ранее запущено, я сразу же представляю главную страницу.

Теперь сказано, что если я инициирую свой «currentPage» как «MainView» или «LoginView», он работает, но НЕ, если он установлен как «WelcomeView». Я предполагаю, что проблема возникает, когда переменная изменяется из подпредставления? Я думал, что использование @EnvironmentObject - способ обойти это ...

Может кто-нибудь объяснить мне, как это работает?

Мои различные файлы:

import SwiftUI
import Combine

class ViewRouter: ObservableObject {

    let objectWillChange = PassthroughSubject<ViewRouter,Never>()

    var currentPage: String = "WelcomeView" {
        didSet {
            objectWillChange.send(self)
        }
    }
}
import SwiftUI

struct ParentView : View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        VStack {
            if viewRouter.currentPage == "WelcomeView" {
                WelcomeView()
            }
            else if viewRouter.currentPage == "MainView" {
                MainView()
            }
            else if viewRouter.currentPage == "LoginView" {
                LoginView()
            }
        }
    }
}
import SwiftUI

struct WelcomeView: View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        ZStack{
            // VStack { [some irrelevant extra code here] }
            VStack {
                    LoginButtons().environmentObject(ViewRouter())
            }
            // VStack { [some irrelevant extra code here] }
        }
    }
}
import SwiftUI

struct LoginButtons: View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        VStack {

            Button(action: {
                self.viewRouter.currentPage = "MainView"
            }) {
                Text("NEW USER")
            }

            Button(action: {
                self.viewRouter.currentPage = "LoginView"
            }) {
                Text("I ALREADY HAVE AN ACCOUNT")
            }
        }
    }
}
import SwiftUI

struct MainView : View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        VStack {
            // Just want to check if it is working for now before implementing the appropriate Views...
            Button(action: {
                self.viewRouter.currentPage = "WelcomeView"
            }) {
                Text("BACK")
            }
        }
    }
}
import SwiftUI

struct LoginView : View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        VStack {
            // Just want to check if it is working for now before implementing the appropriate Views...
            Button(action: {
                self.viewRouter.currentPage = "WelcomeView"
            }) {
                Text("BACK")
            }
        }
    }
}

Заранее большое спасибо! : wink:

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

Хорошо ... Моя «ошибка» заключалась в добавлении дополнительного «.environmentObject (ViewRouter ())» при вызове моего подпредставления «LoginButtons».

Если я удалю его, все заработает! .. Но почему?!?

struct WelcomeView: View {

    @EnvironmentObject var viewRouter: ViewRouter

    var body: some View {
        ZStack{
            // VStack { [some irrelevant extra code here] }
            VStack {
                    LoginButtons()
                       // -->     .environmentObject(ViewRouter())
            }
            // VStack { [some irrelevant extra code here] }
        }
    }
}
0 голосов
/ 18 июня 2020

Итак, в вашем главном окне, в котором вы собираетесь решить, куда отправить своего пользователя, вы можете проверить приложение, было ли оно запущено раньше или нет, в зависимости от того, что вы хотите. Как только вы научитесь это делать, вы сможете адаптироваться к другим вещам. Вот как вы можете проверить это, опять же, в маршрутизаторе основного представления:

    init() {

        // Create initial Data if not data has been setup
        if (InitialAppSetup().initialDataLoaded == false) {
            InitialAppSetup().createInitialData()
        }

        // Onboarding screen
        if !UserDefaults.standard.bool(forKey: "didLaunchBefore") {
            UserDefaults.standard.set(true, forKey: "didLaunchBefore")
            currentPage = "onboardingView"

        } else {
            currentPage = "homeView"
        }
    }

Класс InitialAppSetup () имеет UserDefault, который выглядит следующим образом:

@Published var initialDataLoaded: Bool = UserDefaults.standard.bool(forKey: "InitialData") {
        didSet {
            UserDefaults.standard.set(self.initialDataLoaded, forKey: "InitialData")
        }
    }
...