For my small app I’m navigating from my touchdown web page to a QuestionListView the place every rows of checklist view navigates to a QuestionView. within the QuestionView I’ve mark button. if pressed the questions index is entered or deleted from markedQuestions array located in my EnvironmentObject questionManager.
now what occurs is each time I faucet on the mark button the QuestionView exits to the earlier view. listed below are the codes
struct QuestionsListView: View {
@EnvironmentObject var questionManager: QuestionManager
var categoryName: String
var listStart: Int
var listEnd: Int
var physique: some View {
VStack {
Textual content(categoryName)
.body(maxWidth: .infinity, alignment: .main)
.font(.system(dimension: 24, weight: .daring))
.padding(EdgeInsets(prime: 5, main: 20, backside: 0, trailing: 0))
HStack {
ZStack {
Rectangle()
.foregroundColor(Coloration("BaseColor"))
.cornerRadius(10)
Circle()
.body(width: 50, peak: 50)
.foregroundColor(Coloration(crimson: 0.96, inexperienced: 0.74, blue: 0))
}
.body(width: 80, peak: 80)
ForEach(1 ... 3, id: .self) { _ in
Spacer()
ListFilterButton()
}
}
.padding(EdgeInsets(prime: 0, main: 20, backside: 0, trailing: 20))
Checklist {
ForEach(listStart ... listEnd, id: .self) { index in
ListButtonView(questionNumber: index+1, query: questionManager.questions[index].query, categoryName: categoryName).environmentObject(questionManager)
}
}
}
}
}
struct ListButtonView: View {
@EnvironmentObject var questionManager: QuestionManager
var questionNumber: Int
var query: String
var categoryName: String
var physique: some View {
NavigationLink(vacation spot: QuestionView(
isAnswered: questionManager.isAnswered,
index: questionNumber-1, titleText: categoryName
).environmentObject(questionManager)) {
VStack{
HStack{
Textual content("Query (questionNumber)")
.body(maxWidth: .infinity,alignment: .main)
.font(
.title2
.weight(.daring)
)
if questionManager.isQuestionMarked(index: questionNumber-1) {
Picture(systemName: "flag.fill")
}
Circle()
.body(width: 10, peak: 10)
.foregroundColor(Coloration(crimson: 0.88, inexperienced: 0.26, blue: 0.18))
}
Textual content(query)
.body(maxWidth: .infinity,alignment: .main)
}
}.id(UUID())
.onAppear {
// Add print assertion right here to verify if NavigationLink is showing
print("NavigationLink for Query (questionNumber) appeared.")
}
}
}
struct QuestionView: View {
@EnvironmentObject var questionManager : QuestionManager
@State var isShowingImage = false
@State var isAnswered : Bool
@State var index : Int
@State var isTranslated = false
var titleText: String
var physique: some View {
VStack{
// MARK: Timer and different Informatins
ZStack {
RoundedRectangle(cornerRadius: 10.0)
.stroke(Coloration("BaseColor"),lineWidth: 1)
HStack{
Textual content("20/33")
.font(.caption)
Spacer()
Textual content(titleText)
.font(.title)
.fontWeight(.daring)
Spacer()
TimerView()
}
.padding(.horizontal, 20.0)
}.body(maxHeight: 50)
.padding(.horizontal, 20)
// MARK: Query Card
ZStack{
ZStack{
Rectangle()
.foregroundColor(Coloration("BaseColor"))
.cornerRadius(10)
GeometryReader { geometry in
Circle()
.body(width: 10, peak: 10)
.padding(EdgeInsets(prime: 5, main: geometry.dimension.width - 15, backside: 0, trailing: 0))
.foregroundColor(Coloration(crimson: 0.88, inexperienced: 0.26, blue: 0.18))
}
}
VStack{
// MARK: Translation and Mark Button
HStack {
Textual content("(questionManager.questions[index].id)")
.font(.title2)
.fontWeight(.daring)
Spacer()
Picture(systemName:isTranslated ? "character.bubble.fill" : "character.bubble").onTapGesture {
isTranslated.toggle()
}
MarkButtonView(index: index)
.environmentObject(questionManager)
// Picture(systemName: questionManager.markedQuestions.accommodates(index) ? "flag.fill" : "flag").onTapGesture {
// print(questionManager.markedQuestions)
// questionManager.toggleMarkedQuestion(index: index-1)
// }
}.padding([.top, .leading, .trailing], 20.0)
// MARK: QUESTION AND IMAGE
HStack {
Textual content(isTranslated ? questionManager.questions[index].questionEng : questionManager.questions[index].query)
.font(.headline)
.fontWeight(.mild)
.multilineTextAlignment(.main)
.padding(.main, 20.0)
Spacer()
}
Spacer()
if !(questionManager.questions[index].imageName == ""){
GeometryReader { geometry in
VStack{
Spacer()
Picture(questionManager.questions[index].imageName)
.resizable()
.aspectRatio(contentMode: .match)
.body(maxWidth: geometry.dimension.width)
.cornerRadius(10)
.padding([.leading, .bottom, .trailing], 20.0)
}.onTapGesture {
isShowingImage.toggle()
}
.sheet(isPresented: $isShowingImage) {
Picture(questionManager.questions[index].imageName)
.resizable()
.aspectRatio(contentMode: .match)
}
}
}
}
}
.body(peak: questionManager.questions[index].imageName == "" ? 200 : 400)
.padding([.leading, .bottom, .trailing],20)
// MARK: Reply Choices
VStack{
ScrollView(){
VStack{
ForEach(questionManager.questions[index].solutions){reply in IndividualAnswer(isAnswered: $isAnswered, answerText: reply.textual content, isCorrect: reply.isCorrect)
.cornerRadius(10)
.padding(.horizontal, 20)
}
}
}
}
// MARK: Subsequent and Earlier Buttons
HStack{
Picture(systemName: "chevron.left.circle")
.body(width: 80, peak: 50)
.onTapGesture{if index>0 {index -= 1}
isAnswered = false
}
Spacer()
Picture(systemName: "chevron.proper.circle")
.body(width: 80, peak: 50)
.onTapGesture{index+=1
isAnswered = false
}
}.font(.title)
}
.environmentObject(questionManager)
}
}
class QuestionManager : ObservableObject {
var questions: [Question] = []
var TestQuestions: [Question] = []
var markedQuestions: [Int] {
didSet {
UserDefaults.commonplace.set(markedQuestions, forKey: "markedQuestions")
objectWillChange.ship()
}
}
@Printed var classes: [Category] = []
var isAnswered = false
// @State personal var isMarked: Bool{
// didSet {
// isQuestionMarked(index: Int)
// }
// }
@Printed var selectedState: String {
didSet {
print("Chosen state modified to: (selectedState)")
UserDefaults.commonplace.set(selectedState, forKey: "SelectedState")
updateCategories(for: selectedState)
}
}
var bundesLands = [
Category(id: UUID(), categoryName: "Baden-Württemberg", listStart: 300, listEnd: 309),
Category(id: UUID(), categoryName: "Bayern", listStart: 310, listEnd: 319),
Category(id: UUID(), categoryName: "Berlin", listStart: 320, listEnd: 329),
Category(id: UUID(), categoryName: "Brandenburg", listStart: 330, listEnd: 339),
Category(id: UUID(), categoryName: "Bremen", listStart: 340, listEnd: 349),
Category(id: UUID(), categoryName: "Hamburg", listStart: 350, listEnd: 359),
Category(id: UUID(), categoryName: "Hessen", listStart: 360, listEnd: 369),
Category(id: UUID(), categoryName: "Mecklenburg-Vorpommern", listStart: 370, listEnd: 379),
Category(id: UUID(), categoryName: "Niedersachsen", listStart: 380, listEnd: 389),
Category(id: UUID(), categoryName: "Nordrhein-Westfalen", listStart: 390, listEnd: 399),
Category(id: UUID(), categoryName: "Rheinland-Pfalz", listStart: 400, listEnd: 409),
Category(id: UUID(), categoryName: "Saarland", listStart: 410, listEnd: 419),
Category(id: UUID(), categoryName: "Sachsen", listStart: 420, listEnd: 429),
Category(id: UUID(), categoryName: "Sachsen-Anhalt", listStart: 430, listEnd: 439),
Category(id: UUID(), categoryName: "Schleswig-Holstein", listStart: 440, listEnd: 449),
Category(id: UUID(), categoryName: "Thüringen", listStart: 450, listEnd: 459)
]
struct Class: Identifiable, Hashable {
var id: UUID
var categoryName : String
var listStart : Int
var listEnd : Int
}
// MARK: this one initializes the json file at begin
init() {
// Retrieve the chosen state from UserDefaults, defaulting to "Baden-Württemberg" if not discovered
self.selectedState = UserDefaults.commonplace.string(forKey: "SelectedState") ?? "Baden-Württemberg"
self.markedQuestions = UserDefaults.commonplace.array(forKey: "markedQuestions") as? [Int] ?? []
self.questions = load("questions.json")
// Initialize classes based mostly on the chosen state
updateCategories(for: selectedState)
}
// MARK: Load perform that populate the questions Array with json knowledge
func loadTestQuestions(){
func getRandomQuestions(from vary: Vary<Int>, depend: Int) -> [Question] {
let selectedQuestions = Array(questions[range].shuffled().prefix(depend))
return selectedQuestions
}
// Choose 10 random questions from the primary 100
let firstHundredQuestions = getRandomQuestions(from: 0..<100, depend: 10)
// Choose 10 random questions from the second 100
let secondHundredQuestions = getRandomQuestions(from: 100..<200, depend: 10)
// Choose 10 random questions from the third 100
let thirdHundredQuestions = getRandomQuestions(from: 200..<300, depend: 10)
// Choose 3 random questions from the remaining questions
let remainingQuestions = getRandomQuestions(from: classes[3].listStart..<classes[3].listEnd, depend: 3)
// Concatenate all chosen questions right into a single array
let selectedQuestions = firstHundredQuestions + secondHundredQuestions + thirdHundredQuestions + remainingQuestions
TestQuestions = selectedQuestions
}
func load<T: Decodable>(_ filename: String) -> T {
let knowledge: Information
guard let file = Bundle.primary.url(forResource: filename, withExtension: nil)
else {
fatalError("Could not discover (filename) in primary bundle.")
}
do {
knowledge = strive Information(contentsOf: file)
} catch {
fatalError("Could not load (filename) from primary bundle:n(error)")
}
do {
let decoder = JSONDecoder()
return strive decoder.decode(T.self, from: knowledge)
} catch {
fatalError("Could not parse (filename) as (T.self):n(error)")
}
}
func changeSelectedState(to newState: String) {
guard bundesLands.map({ $0.categoryName }).accommodates(newState) else {
// Deal with the case the place newState is just not a sound state
return
}
selectedState = newState
// The didSet block of selectedState will deal with the remainder
}
// Replace classes based mostly on the chosen state
personal func updateCategories(for state: String) {
classes = [
Category(id: UUID(), categoryName: "Basic Laws", listStart: 0, listEnd: 99),
Category(id: UUID(), categoryName: "Politics", listStart: 100, listEnd: 199),
Category(id: UUID(), categoryName: "History", listStart: 200, listEnd: 299),
Category(id: UUID(), categoryName: state, listStart: bundesLands.first(where: { $0.categoryName == state })?.listStart ?? 0,
listEnd: bundesLands.first(where: { $0.categoryName == state })?.listEnd ?? 0)
// Add more categories as needed
]
}
// MARK: marked query replace perform, marked questions will save the ids
func toggleMarkedQuestion(index: Int) {
print("Toggling marked query at index: (index)")
var markedSet = Set(markedQuestions)
if markedSet.accommodates(index+1) {
markedSet.take away(index+1)
} else {
markedSet.insert(index+1)
}
markedQuestions = Array(markedSet)
}
// checks an index if marked or not
func isQuestionMarked(index: Int) -> Bool {
return markedQuestions.accommodates(index)
}
}