Как перемещать представления в SwiftUI нажатием кнопки или добавить действие в NavigationLink?

#ios #swift #xcode #swiftui

#iOS #swift #xcode #swiftui

Вопрос:

Я знаю, что этот вопрос задавали уже миллион раз, но я все еще не могу найти на него хорошего ответа, несмотря ни на что.

Работал с SwiftUI (только начинал) и использовал существующий код для включения регистрации / входа в Firebase по телефону.

Поток

  1. Отображается экран загрузки (OnboardingStepView)
  2. Отображается экран ввода телефона (LoginView)
  3. Отображается проверка номера телефона (VerificationView)
  4. Отображается просмотр дополнительных пользовательских данных (RegisterView)
  5. Перейдите на домашнюю страницу (домашний просмотр)

В моем первом представлении (contentView) У меня есть следующий код:

     struct ContentView: View {
    @AppStorage("log_Status") var status = false

    @State private var onboardinDone = false
    var data = OnboardingDataModel.data
    var body: some View {
        
        ZStack{
            Group {
                if !onboardinDone {
                    OnboardingViewPure(data: data, doneFunction: {
                        status = true
                        self.onboardinDone = true
                        
                        print("done onboarding")
                    })
                
            } else {
                
                NavigationView{
                    
                    VStack{
                        
                        if status{Home()}
                        else{Login()}
                    }
                    .preferredColorScheme(.dark)
                    .navigationBarHidden(true)
                }
            }
        }
    }
}
}
 

Теперь все представления закодированы и работают должным образом (с Firebase), и в предыдущих версиях Swift я бы переходил при нажатии кнопки. Однако в SwiftUI это невозможно, и вам нужно использовать навигационные ссылки сейчас (которые могут выглядеть как кнопка).

В качестве примера, в моем «VerficationView» есть кнопка, которая выполняет действие.

Кнопка (действие: loginData.verifyCode) {

Теперь, после нажатия кнопки и проверки данных в фоновом режиме, я хочу перейти к следующему созданному мной представлению, в котором регистрируются «имя, биография и изображение» пользователя (RegisterView). Это представление работает и регистрирует данные пользователя в Firebase. Однако я не знаю, как правильно представить этот экран, как только пользователь нажимает на вышеупомянутую кнопку.

  • Должен ли я изменить кнопку на навигационную ссылку и могу ли я добавить к ней действие?
  • Должен ли я использовать @State для установки состояния просмотра и «isActive» для отслеживания отображаемого?
  • Использую ли я «материнский вид», и этот вид всегда отслеживает, какой вид отображается?

Пожалуйста, дайте мне знать ваши мысли, потому что я застрял и не уверен, как продолжить….

Спасибо!

Ответ №1:

Я бы опубликовал это как комментарий, но у меня недостаточно репутации.

Я решил аналогичную проблему, показав экран входа в систему как .fullScreenCover. Это выводит его из обычной иерархии навигации, поэтому contentView по-прежнему является корневым представлением. После завершения входа в систему измените Bool в contentView с помощью @Binding . Это изменит состояние contentView, так что теперь ifelse может отправить пользователя на вашу первую страницу.

 .fullScreenCover(isPresented: $isPresented) {
 

Редактировать:

Может быть, нет необходимости просто else if в полноэкранном режиме. Смотрите ниже.

 struct ContentView: View {
    
    @State private var isOnboardinDone: Bool = false
    @State private var isLoggedIn: Bool = false
    
    var body: some View {
        if isOnboardinDone amp;amp; isLoggedIn {
            FirstView()
        } else if !isOnboardinDone {
            OnboardingView(done: $isOnboardinDone)
        } else {
            LoginView(loggedIn: $isLoggedIn)
        }
        
    }
}
 
 struct FirstView: View {
    var body: some View {
        Text("First")
    }
}

 
 struct OnboardingView: View {
    @Binding var done: Bool
    var body: some View {
        Button(action: { done.toggle() }, label: {
            Text("On Boarding done.")
        })
    }
}
 
 struct LoginView: View {
    @Binding var loggedIn: Bool
    var body: some View {
        Button(action: { loggedIn.toggle() }, label: {
            Text("Login")
        })
    }
}
 

Комментарии:

1. Спасибо за предложение! Но как это будет работать, если мой экран загрузки отображается первым, если я перекрываю его экраном входа в систему?

2. Потрясающе, спасибо! Поиграем с этим. Итак, в принципе, лучший способ — поиграть с состояниями переменных и привязать их к другим представлениям?

3. Не беспокойтесь. Вы также можете прикрепить sheets и fullScreenCover к EmptyView()

4. В моем случае это не работает, поскольку в кнопке есть действие, и оно просит меня удалить действие, чтобы добавить переключатель… Это сводит меня с ума, потому что простой вариант перехода был простым, и теперь я изучил это снова, ха-ха

5. Я немного застрял, чтобы помочь без дополнительного кода или сообщений об ошибках.