NavigationLink: показать промежуточный вид с опросом и после его закрытия — перейти к представлению «назначения»

#swiftui-list #swiftui-navigationlink #swiftui-navigationview

#swiftui-список #swiftui-navigationlink #swiftui-navigationview

Вопрос:

В приложении my fitness пользователь видит список доступных тренировок, этот список реализован по следующей структуре

 ForEach(self.mainData.journeys) { journeyDraft in
                        NavigationLink(destination:
                            VStack { [data] }
                        )
}
 

(см. Полный код ниже)

[data] содержит длинный блок if { } else { } if { } else { }, включающий несколько сценариев — setView / WeekView / BuildWeekView / GenerateJourney (назовем их все GoToView), в зависимости от настроек и состояния обучения (новое обучение или уже начатое).

Здесь возникает проблема.. Пользователь нажимает на какую-либо тренировку из списка, и перед отправкой пользователя в соответствующий вид (GoToView) из NavigationLink я проверяю, завершил ли он опрос уровня пригодности:

 self.mainData.customerData?.fitnessLevel != nil
 

И если он еще этого не сделал, мне нужно сначала показать ему обзор. И только после того, как он завершит опрос — он отправляется дальше в GoToView.. (Если пользователь уже заполнил опрос, он отправляется прямо в GoToView, а не отображается вид опроса)

Как бы вы порекомендовали реализовать это промежуточное представление, чтобы, когда он ответил на мой вопрос, он перешел к GoToView?

У меня есть 4 разных сценария (setView, WeekView, BuildWeekView, GenerateJourney) внутри этого блока if / else, и я не хочу включать представление опроса внутри каждого из них.. Я хочу найти какой-то способ показать представление ПЕРЕД отправкой пользователя в пункт назначения NavigationLink (GoToView).

Любая помощь приветствуется!

 var body: some View {
        NavigationView {
            ZStack {
                ProfileView()
                .opacity(self.showProfile ? 1 : 0)
            VStack {
                Image(customImage: ((self.thisSession.profile.photo != nil) ? self.thisSession.profile.photo : Constants.defaultProfileImage)!)!
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 50, height: 50)
                        .clipShape(Circle())
                        .overlay(Circle().stroke(Color.blue, lineWidth: 3))
                    .onTapGesture {
                        self.showProfile.toggle()
                    }
                List {
                    ForEach(self.mainData.journeys) { journeyDraft in
                        NavigationLink(destination:
                            VStack {
                                
                                // if fitness survey IS COMPLETED but journey was not yet created
                                if (self.mainData.customerData?.fitnessLevel != nil amp;amp; self.mainData.userJourneys[journeyDraft.journeyId!] == nil) {
                                    
                                    // if it's NOT a single day training, no need to return to it? why..?
                                    if journeyDraft.type != Constants.singleDay {
                                        VStack {
                                            //Text("Section 1").foregroundColor(.blue)
                                            DeferView { BuildWeekView(journeyDraftId: journeyDraft.journeyId, customerData: self.mainData.customerData)
                                            .navigationBarHidden(true)
                                            .navigationBarTitle("")
                                            }
                                        }
                                    } else {
                                        
                                        VStack {
                                            DeferView { GenerateJourney(schedule: [:], tools: [:], journeyDraft: journeyDraft,  thisSession: self.thisSession, goto: Constants.goToDay)
                                                .navigationBarHidden(true)
                                                .navigationBarTitle("")
                                            }
                                        }
                                    }
                                    
                                // if fitnessLevel is set and this is not a first launch
                                } else if (self.mainData.customerData?.fitnessLevel != nil amp;amp; self.mainData.userJourneys[journeyDraft.journeyId!] != nil) {
                                    // multiple day training
                                    if (self.mainData.userJourneys[journeyDraft.journeyId!]!.type! == Constants.singleDay) {
                                                                        VStack {
                                                                            WeekView(journey: self.mainData.userJourneys[journeyDraft.journeyId!]!)
                                                                            .navigationBarHidden(true)
                                                                            .navigationBarTitle("")
                                                                        }
                                                                    } else {
                                                                            // it's a single day training
                                                                        VStack {
                                                                            SetView(journey:self.mainData.userJourneys[journeyDraft.journeyId!]!,day:self.mainData.userJourneys[journeyDraft.journeyId!]!.days.keys.first!)
                                                                            .navigationBarHidden(true)
                                                                            .navigationBarTitle("")
                                                                        }
                                                                    }
                                        
                                // if survey is not completed and this is a first launch (but we need to run GenerateJourney then
                                } else if (self.mainData.customerData?.fitnessLevel == nil) {
                                   // HERE WE NEED TO SHOW THE SURVEY AND AFTER IT IS COMPLETED - DO THE SAME AS ABOVE
                                }

                            }
                        ) {
                            Image(customImage: journeyDraft.image!)!
                                .resizable()
                                .renderingMode(.original)
                                .frame(height: 150, alignment: .leading)
                                .opacity( (self.mainData.userJourneys[journeyDraft.journeyId!] == nil) ? 1 : 0.5 )
                                .overlay(
                                    Text("(journeyDraft.name!) : (journeyDraft.type!)")
                                        .font(.largeTitle)
                                        .fontWeight(.semibold)
                                        .foregroundColor((self.mainData.userJourneys[journeyDraft.journeyId!] == nil) ? .white : .red)
                            )
                        }
                    }
                }
            }
            .opacity(self.showProfile ? 0 : 0.6)
            
            }
        }
        .navigationBarHidden(true)
        .navigationBarTitle("")
    }
}
 

Ответ №1:

Я решил проблему, используя теги в NavigatingLink