SwiftUI Navigation Путь инициализации стека с onAppear не отображает правильный экранIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 SwiftUI Navigation Путь инициализации стека с onAppear не отображает правильный экран

Сообщение Anonymous »

Я новичок в разработке SwiftUI. Пытаюсь создать свое первое настоящее приложение! Я все еще занимаюсь навигацией и аутентификацией, пытаясь отобразить правильные экраны независимо от того, является ли authState неаутентифицированным или аутентифицированным. однако мое приложение не запускается на правильном экране, в зависимости от состояния оно просто вылетает без сообщения об ошибке.
У меня есть класс Router с одним перечислением Routes для всех моих маршрутов. .

Код: Выделить всё

final class Router: ObservableObject {
public enum Routes: Hashable {
case landing
case emailAuth
case home
}

@Published var path: [Routes] = []

func navigate(to destination: Routes) {
path.append(destination)
}

func navigateBack() {
path.removeLast()
}

func navigateToRoot() {
path.removeLast(path.count)
}
}
это моя модель AuthViewModel, в которой я использую Firebase addStateDidChangeListener для прослушивания изменений состояния:

Код: Выделить всё

enum AuthState {
case unAuthenticated
case authenticated
}

@MainActor
class AuthViewModel: ObservableObject {
@AppStorage("email") var emailStore: String?
@Published var email = ""
@Published var errorMessage = ""

@Published var authState: AuthState = .unAuthenticated
@Published var user: User?
@Published var userEmail = ""

init() {
registerAuthStateHandler()
}

private var authStateHandle: AuthStateDidChangeListenerHandle?

func registerAuthStateHandler() {
if authStateHandle == nil {
authStateHandle = Auth.auth().addStateDidChangeListener{auth, user in
self.user = user
self.userEmail = user?.email ?? "(unknown)"

if (user != nil) {
self.authState = .authenticated
} else {
self.authState = .unAuthenticated
}
print("Curr authState: \(self.authState)")
}
}
}
}

...
Я думаю, что правильно объявляю свой маршрутизатор с помощью @StateObject в пределах моего поля зрения?:

Код: Выделить всё

struct ContentView: View {
@StateObject var authViewModel: AuthViewModel = AuthViewModel()
@StateObject var router: Router = Router()

var body: some View {
NavigationStack(path: $router.path) {
//    Text("Loading...")
LandingScreen(path: $router.path)
.navigationDestination(for: Router.Routes.self) { route in
switch route {
case .landing:
let _ = print("landing")
LandingScreen(path: $router.path)
case .emailAuth:
AuthEmail(path: $router.path)
case .home:
Text("TODO: home page")
}
}
}
.onAppear {
print("Curr authState: \(authViewModel.authState)")
if (authViewModel.authState == .authenticated) {
router.path = [.home]
} else {
router.path = [.landing]
}
print(router.path)
}
.environmentObject(router)
.environmentObject(authViewModel)
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(AuthViewModel())
.environmentObject(Router())
}
}
в моих подпредставлениях у меня есть что-то вроде:

Код: Выделить всё

struct LandingScreen: View {
@EnvironmentObject var authViewModel: AuthViewModel
@Binding var path: [Router.Routes]

var body: some View {
// ...
NavigationStack {
NavigationLink(value: Router.Routes.emailAuth) {
Text("Continue with email")
}
}
}
я пробовал изменить начальный экран в моем NavigationStack на простой текст («Загрузка...»), однако мой экран остается на «loading. ..» и не меняет экран на LandingScreen. несмотря на то, что мои журналы печати говорят, что путь установлен правильно:

Код: Выделить всё

Curr authState: unAuthenticated
[app.Router.Routes.landing]
landing
Я также попытался переместить свой код onAppear в init(), но ожидается, что init будет вызываться несколько раз и все равно останется на экране загрузки, так что это бесполезно...Я также пытался переместить init() на маршрутизатор, но столкнулся с той же проблемой.

Подробнее здесь: https://stackoverflow.com/questions/784 ... -correct-s
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»