I was wondering if anybody could help with achieving the following using the new navigationDestination
API. Currently, I am creating a CoreData entity within a child view (AddEventsView
) and then opening the recently created entity by passing the id from the AddEventsView
back up to the EventsView
using @Binding.
EventsView
struct EventsView: View {
@FetchRequest(sortDescriptors: []) var festivals: FetchedResults<Festivals>
@Environment(\.managedObjectContext) var moc
@State var showEditView = false
@State var recentlyAddedFestivalId: UUID!
var body: some View {
NavigationStack {
VStack {
if showEditView {
Group {
Spacer().frame(height: 20)
AddEventsView(showEditView: $showEditView, recentlyAddedFestivalId: $recentlyAddedFestivalId)
Spacer().frame(height: 20)
Divider()
}
.padding(.leading, 20)
.padding(.trailing, 20)
}
// TODO: Migrate to the new navigationDestination API
List(festivals) { festival in
NavigationLink(
destination: TestView2(festivalName: festival.festival_name!, startDate: festival.start_date!, endDate: festival.end_date!),
tag: festival.id!,
selection: $recentlyAddedFestivalId
){
VStack {
Text("Item: \(festival.id!)")
Text(festival.festival_name ?? "Unknown")
TestView()
}
}
.listRowSeparator(.hidden)
.listRowInsets(.init(top: 20, leading: 20, bottom: 20, trailing: 20))
}
.listStyle(.plain)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
withAnimation(.easeInOut(duration: 0.25)) {
showEditView.toggle()
}
}) {
Image(systemName: "plus")
}
}
}
.navigationTitle("Events")
}
}
}
AddEventsView
struct AddEventsView: View {
@State private var festivalName: String = ""
@State private var startDate = Date.now
@State private var endDate = Date.now
@Binding var showEditView: Bool
@Binding var recentlyAddedFestivalId: UUID!
@FocusState private var focusedField: FocusedField?
@Environment(\.managedObjectContext) var moc
var body: some View {
VStack(spacing: 20) {
TextField("**Festival Name**", text: $festivalName)
.submitLabel(.next)
.autocorrectionDisabled()
.font(.title3)
.focused($focusedField, equals: .festivalName)
.textInputAutocapitalization(.words)
DatePicker(selection: $startDate, in: Date.now..., displayedComponents: .date) {
Text("**Start Date**")
}
.onTapGesture {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
DatePicker(selection: $endDate, in: Date.now..., displayedComponents: .date) {
Text("**End Date**")
}
.onTapGesture {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
Button(action: {
let festival = Festivals(context: moc)
festival.id = UUID()
festival.festival_name = festivalName
festival.start_date = startDate
festival.end_date = endDate
try? moc.save()
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
withAnimation(.easeInOut(duration: 0.25)) {
showEditView.toggle()
recentlyAddedFestivalId = festival.id
print(recentlyAddedFestivalId.debugDescription)
}
}
}) {
Text("Done")
.padding(10)
.frame(minWidth: 300)
}
.foregroundStyle(.white)
.background(.blue)
.clipShape(RoundedRectangle(cornerRadius: 8))
.padding(.top, 20)
}
.padding()
.background(.regularMaterial)
.cornerRadius(8)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
self.focusedField = .festivalName
}
}
}
}
Below is a video of the behavior im trying to achieve.
I took a look at Apple's documentation here but failed to get it to work.
I have also looked at other questions on SO regarding migrating here but have not been able to achieve the above behavior.