Search code examples
iosswiftswiftuiswiftui-navigationlink

When I interact with an element in a navLink, the app glitches and returns me to the previous screen


I've been working on this app and ran into a problem, I have some nested navLinks and if I interact with certain elements in one of them, the app glitches, and sends me back to the previous page. I have no clue what is going on, and any advice is hugely appreciated. Here is my code, I know it is a lot but I really don't know where the problem is, so sorry for how much code I am posting:

//
//  ContentView.swift
//  Scholar Hours App
//
//  Created by Evan Scharnhorst on 8/13/22.
//

import SwiftUI

extension Array: RawRepresentable where Element: Codable {
    public init?(rawValue: String) {
        guard let data = rawValue.data(using: .utf8),
              let result = try? JSONDecoder().decode([Element].self, from: data)
        else {
            return nil
        }
        self = result
    }

    public var rawValue: String {
        guard let data = try? JSONEncoder().encode(self),
              let result = String(data: data, encoding: .utf8)
        else {
            return "[]"
        }
        return result
    }
}

struct ContentView: View {
        @State var hours = 7
    @State var minutes: Double = 0
    @AppStorage("log") var log: [String] = []
    var time = Date.now
    let formatter1 = DateFormatter()
    var isStripe = 0
    @AppStorage("hoursGoal") var hoursGoal = 0
    @AppStorage("minutesGoal") var minutesGoal = 0
    @AppStorage("practiceScholar") var practiceScholar = true
    @AppStorage("weeklyScholarDays") var weeklyScholarDays = 3
    
    func incrementStep() {
       minutesGoal += 30
       if (minutesGoal == 60) {
           hoursGoal += 1
           minutesGoal = 0
       }
    }

    func decrementStep() {
       minutesGoal -= 30
       if (minutesGoal == -30) {
           hoursGoal -= 1
           minutesGoal = 30
       }
    }
    
    
        var body: some View {
            NavigationView {
                VStack{
                    NavigationLink {
                        List{
                            Section {
                                    Stepper("\(hours) hours", value: $hours, in: 3...12)
                            }header: {
                                    Text("Scholar Hours")
                            }
                                Section{
                                Slider(value: $minutes,in: 0...59, step: 1)
                                Text("\(Int(minutes)) minutes")
                            } header: {
                                Text("Scholar Minutes")
                            }
                            
                            Section{
                                Button("Log Hours") {
                                    formatter1.dateStyle = .short
                                    log.insert(formatter1.string(from: time), at: 0)
                                    log.insert("\(hours)h \(Int(minutes))m", at: 0)
                                    print(log)
                                }
                            }footer: {
                                Text("Your log will be editable. To edit, please go to the \("\"Log\"") page.")
                            }
                        }
                    .navigationTitle("Scholar")
                    }label: {
                        Text("Scholar")
                            .font(.title)
                    }
                    
                    NavigationLink(destination: Text("Second View")) {
                        Text("Love of Learning")
                            .font(.title)
                    }
                    NavigationLink(destination: Text("Second View")) {
                        Text("Break")
                            .font(.title)
                    }
                    NavigationLink {
                        List {
                            Section{
                                Text("5h 32m")
                                    .font(.system(size: 45, weight: .bold, design: .default))
                                    .frame(maxWidth: .infinity, alignment: .center)
                                    .padding(20)
                                NavigationLink{
                                     Text("Blah, Blah, Blah")
                                        .navigationTitle("More Stats")
                                }label: {
                                    Text("More Stats")
                                }
                            }header: {
                                Text("Extra Hours")
                                    .padding(0)
                                    
                            }
                            
                                
                        
                            Section {
                                
                                
                                
                                NavigationLink {
                                    List {
                                        Section{
                                            Stepper {
                                                Text("\(hoursGoal)h \(minutesGoal)m")
                                            } onIncrement: {
                                               
                                                minutesGoal += 30
                                                if (minutesGoal == 60) {
                                                    hoursGoal += 1
                                                    minutesGoal = 0
                                                }
                                                
                                            } onDecrement: {
                                                minutesGoal -= 30
                                                if (minutesGoal == -30) {
                                                    hoursGoal -= 1
                                                    minutesGoal = 30
                                                }
                                            }
                                        } header: {
                                            Text("Daily Goal")
                                        }footer: {
                                            Text("How many scholar hours per scholar day.")
                                        }
                                        Section {
                                            Toggle("Practice Scholar", isOn: $practiceScholar)
                                        }footer: {
                                            Text("Practice scholar means that you will a some love of learning days in your week")
                                        }
                                        if(practiceScholar == true){
                                            Section {
                                                Stepper("\(weeklyScholarDays) days", value: $weeklyScholarDays, in: 1...4)
                                            }header: {
                                                Text("Weekly Scholar Days")
                                            }footer: {
                                                Text("How many scholar days per week.")
                                            }
                                        }
                                    }
                                    .navigationTitle("Settings")
                                }label: {
                                    Text("Settings")
                            }
                                
                                
                                
                                
                                
                                
//                                NavigationLink {
//                                    if(log != []){
//                                        List(log, id: \.self) { i in
//                                            HStack {
//                                                if((Int(i) ?? 0) % 2 == 0) {
//                                                 Text(i)
//                                                 Spacer()
//                                                 Text(log[(Int(i) ?? 0) + 1])
//                                                }
//                                            }
//                                            .navigationTitle("Log")
//
//                                        }
//                                        .listStyle(GroupedListStyle())
//                                    }else{
//                                        Text("Uh oh, there are no logs, you can log your study time in \("\"Scholar\"") or \("\"Love of Learning\"").")
//                                            .padding(30)
//                                            .navigationTitle("Log")
//                                    }
//
//
//                                }label: {
//                                    Label("Log", systemImage: "clock.fill")
//                                        .foregroundColor(.white)
//                                }
                                
                                NavigationLink {
                                    Text("book log view")
                                        .navigationTitle("Book Log")
                                }label: {
                                    Label("Book Log", systemImage: "book.closed.fill")
                                        .foregroundColor(.white)
                                }
                            }
                        }
                        .navigationTitle("Dashboard")
                        }label: {
                            Text("Dashboard")
                                .font(.title)
                        }
                }
                
                .buttonStyle(.bordered)
                .padding()
                .navigationBarTitle("Log Hours")
            }
        }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

And the problem with this is, when I run it, then go to Dashboard/Settings, and toggle the switch or increment or decrement the stepper, it sends me back to the dashboard. When I do this I also get this error in the debug console:

Will attempt to recover by breaking constraint <NSLayoutConstraint:0x6000004fbf20 UIView:0x7fbc937277d0.trailing == _UIBackButtonMaskView:0x7fbc93727650.trailing (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. Message from debugger: Terminated due to signal 9

Thanks to anybody who takes the time to help me out. I appreciate it.


Solution

  • For you to start with I just added 2 view struct ScholarView and DashboardView which now make navigation work correctly :

    struct ContentView: View {
        @State var hours = 7
        @State var minutes: Double = 0
        var time = Date.now
        
        var body: some View {
            NavigationView {
                VStack{
                    NavigationLink {
                        ScholarView(hours: $hours, minutes: $minutes, time: time)
                    } label: {
                        Text("Scholar")
                            .font(.title)
                    }
                    
                    NavigationLink(destination: Text("Second View")) {
                        Text("Love of Learning")
                            .font(.title)
                    }
                    NavigationLink(destination: Text("Second View")) {
                        Text("Break")
                            .font(.title)
                    }
                    NavigationLink {
                        DashboardView()
                    } label: {
                        Text("Dashboard")
                            .font(.title)
                    }
                }
                
                .buttonStyle(.bordered)
                .padding()
                .navigationBarTitle("Log Hours")
            }
        }
    }
    
    struct ScholarView: View {
        @Binding var hours: Int
        @Binding var minutes: Double
        var time: Date
        let formatter1 = DateFormatter()
        @AppStorage("log") var log: [String] = []
    
        var body: some View {
            List{
                Section {
                    Stepper("\(hours) hours", value: $hours, in: 3...12)
                }header: {
                    Text("Scholar Hours")
                }
                Section{
                    Slider(value: $minutes,in: 0...59, step: 1)
                    Text("\(Int(minutes)) minutes")
                } header: {
                    Text("Scholar Minutes")
                }
                
                Section{
                    Button("Log Hours") {
                        formatter1.dateStyle = .short
                        log.insert(formatter1.string(from: time), at: 0)
                        log.insert("\(hours)h \(Int(minutes))m", at: 0)
                        print(log)
                    }
                }footer: {
                    Text("Your log will be editable. To edit, please go to the \("\"Log\"") page.")
                }
            }
            .navigationTitle("Scholar")
        }
    }
    
    struct DashboardView: View {
        @AppStorage("hoursGoal") var hoursGoal = 0
        @AppStorage("minutesGoal") var minutesGoal = 0
        @AppStorage("practiceScholar") var practiceScholar = true
        @AppStorage("weeklyScholarDays") var weeklyScholarDays = 3
    
        var body: some View {
            List {
                Section{
                    Text("5h 32m")
                        .font(.system(size: 45, weight: .bold, design: .default))
                        .frame(maxWidth: .infinity, alignment: .center)
                        .padding(20)
                    NavigationLink{
                        Text("Blah, Blah, Blah")
                            .navigationTitle("More Stats")
                    }label: {
                        Text("More Stats")
                    }
                } header: {
                    Text("Extra Hours")
                        .padding(0)
                }
                Section {
                    NavigationLink {
                        List {
                            Section{
                                Stepper {
                                    Text("\(hoursGoal)h \(minutesGoal)m")
                                } onIncrement: {
                                    incrementStep()
                                } onDecrement: {
                                    decrementStep()
                                }
                            } header: {
                                Text("Daily Goal")
                            }footer: {
                                Text("How many scholar hours per scholar day.")
                            }
                            Section {
                                Toggle("Practice Scholar", isOn: $practiceScholar)
                            }footer: {
                                Text("Practice scholar means that you will a some love of learning days in your week")
                            }
                            if(practiceScholar == true){
                                Section {
                                    Stepper("\(weeklyScholarDays) days", value: $weeklyScholarDays, in: 1...4)
                                }header: {
                                    Text("Weekly Scholar Days")
                                }footer: {
                                    Text("How many scholar days per week.")
                                }
                            }
                        }
                        .navigationTitle("Settings")
                    }label: {
                        Text("Settings")
                    }
                    //                                NavigationLink {
                    //                                    if(log != []){
                    //                                        List(log, id: \.self) { i in
                    //                                            HStack {
                    //                                                if((Int(i) ?? 0) % 2 == 0) {
                    //                                                 Text(i)
                    //                                                 Spacer()
                    //                                                 Text(log[(Int(i) ?? 0) + 1])
                    //                                                }
                    //                                            }
                    //                                            .navigationTitle("Log")
                    //
                    //                                        }
                    //                                        .listStyle(GroupedListStyle())
                    //                                    }else{
                    //                                        Text("Uh oh, there are no logs, you can log your study time in \("\"Scholar\"") or \("\"Love of Learning\"").")
                    //                                            .padding(30)
                    //                                            .navigationTitle("Log")
                    //                                    }
                    //
                    //
                    //                                }label: {
                    //                                    Label("Log", systemImage: "clock.fill")
                    //                                        .foregroundColor(.white)
                    //                                }
                    NavigationLink {
                        Text("book log view")
                            .navigationTitle("Book Log")
                    }label: {
                        Label("Book Log", systemImage: "book.closed.fill")
                            .foregroundColor(.white)
                    }
                }
            }
            .navigationTitle("Dashboard")
        }
    
        func incrementStep() {
            minutesGoal += 30
            if (minutesGoal == 60) {
                hoursGoal += 1
                minutesGoal = 0
            }
        }
        
        func decrementStep() {
            minutesGoal -= 30
            if (minutesGoal == -30) {
                hoursGoal -= 1
                minutesGoal = 30
            }
        }
        
    }