Calling a view from 2 different places, one works one doesn't

I am calling JobOverView from two spots in JobsView. One is in a NavigationLink and works as expected. The other is in the addJob function and it doesn't work much at all.

For one, it gives a warning that I'm not doing anything with the return value. What return value? I'm assuming its trying to return a view but why only here and not in the nav link? In any case, I can silence it with let _ =.

When I call it in addJob and trace through in the debugger it bounces around the variables I declare in JobOverView but never gets to the body at all.

Is there another way I should be going about this?


The code:
Code Block SwiftUI
struct JobsView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Job.timestamp, ascending: true)],
animation: .default)
private var jobs: FetchedResults<Job>
var body: some View {
NavigationView {
List {
ForEach(jobs) { job in
NavigationLink ("\(job.name!)") destination: JobOverView(job: job))
}
.onDelete(perform: deleteJobs)
}
.toolbar {
Button(action: addJob) {
Label("Add Job", systemImage: "plus")
}
}
.navigationTitle("Jobs")
}
}
private func addJob() {
withAnimation {
let newJob = Job(context: viewContext)
newJob.timestamp = Date()
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
let _ = JobOverView(job: newJob)
}
}
}


Code Block SwiftUI
struct JobOverView: View {
@State var jobEditState = JobEditState.closed
@ObservedObject var job: Job
var body: some View {
VStack {
HStack {
if jobEditState == .closed {
Button(action: { jobEditState = .info }) {
Label("Job Info", systemImage: "chevron.down.circle.fill")
Spacer()
}
.padding(.leading)
} else if jobEditState == .info {
JobInfoView(job: job, jobEditState: $jobEditState)
} else if jobEditState == .editing {
JobEditView(job: job, jobEditState: $jobEditState)
}
}
List {
ForEach(job.roomsArray) { room in
NavigationLink (destination: RoomEditView(room: room)) { RoomView(room: room) }
}
.onDelete(perform: deleteRooms)
}
}




Accepted Reply

I think I see what you are doing there, your code runs fine and have tried to implement it in my own. The result? The compiler is unable to type-check this expression in reasonable time...

I have it narrowed down to the navlink. If I get rid of tag: and selection: it compiles just fine, if I add either of them back, I get the compiler message. It's not that complicated a view. I've tried replacing RoomView with a Text("") same deal. I think I'm doing it right, it just wont compile. I've tried making selection an Int a String and a UUID no difference.

Code Block
NavigationLink (destination: RoomEditView(room: room),
tag: room.uuid,
selection: selection) {
RoomView(room: room)}


Replies

I understood that you would a single click on the "+" button create a new List's item and follows its link.
If it is so the NavigationLink init has to be the one with a tag and reference to a tags' selection, the addJob function have to create the new job's item and set the reference to point to it.
The simplified code below use an, improper, set of Int as job's ID.
Code Block
import SwiftUI
struct ContentView: View {
    var body: some View {
JobsView()
    }
}
extension Int: Identifiable
{
public var id: Self { self }
}
struct JobsView: View {
@State private var jobs = [0, 1, 2]
@State private var selection: Int? = nil
var body: some View {
NavigationView {
List {
ForEach(jobs) { job in
NavigationLink("job \(job)",
  destination: JobOverView(job: job),
  tag: job,
  selection: $selection)
}
}
.toolbar {
Button(action: addJob,
  label: {Image(systemName:"plus")}
)
}
.navigationTitle("Jobs")
}
}
private func addJob() {
jobs.append(jobs.last!+1)
selection = jobs.last
  }
}
struct JobOverView: View {
let job: Int
var body: some View {
Label("Job Info \(job)", systemImage:  "chevron.down.circle.fill")
}
}

I think I see what you are doing there, your code runs fine and have tried to implement it in my own. The result? The compiler is unable to type-check this expression in reasonable time...

I have it narrowed down to the navlink. If I get rid of tag: and selection: it compiles just fine, if I add either of them back, I get the compiler message. It's not that complicated a view. I've tried replacing RoomView with a Text("") same deal. I think I'm doing it right, it just wont compile. I've tried making selection an Int a String and a UUID no difference.

Code Block
NavigationLink (destination: RoomEditView(room: room),
tag: room.uuid,
selection: selection) {
RoomView(room: room)}