#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