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.
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
}
}
}