Update: I refactored it a bit to use @ObservableObject
, but the issue still persists
In my SwiftUI app, I have a LazyVGrid
populated with n cards and one New Event button. When I press the New Event button, I have a custom modal overlaying the View to let the user add a new event. However, after dismissing the view (by tapping a Create Event
button), the modal disappears however the new event card isn't added to the LazyVGrid
. It only appears once I force quit the app and re-open it.
Here is the main ContentView
:
struct ContentView: View {
@State var progress: Double = 0.0
@State var editMode: Bool = false
@State var angle: Double = 0
@State var showModal: Bool = false
@ObservedObject var model: Model
var columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: 10), count: 2)
func animate(while condition: Bool) {
self.angle = condition ? -0.6 : 0
withAnimation(Animation.linear(duration: 0.125).repeatForever(while: condition)) {
self.angle = 0.6
}
if !condition {
self.angle = 0
}
}
var body: some View {
ZStack {
NavigationView {
LazyVGrid(columns: columns, spacing: 10) {
ForEach(model.events, id: \.self) { event in
SmallCardView(event: event, angle: $angle)
}
if !showModal {
AddEventButtonView(
editMode: $editMode,
showModal: $showModal,
namespace: namespace
)
} else {
Spacer().frame(height: 100)
}
}
.onLongPressGesture {
if !self.editMode {
self.editMode = true
animate(while: self.editMode)
}
}
}
if self.showModal {
AddEventView(namespace: namespace, events: self.$model.events, showModal: $showModal)
}
}
}
}
This is the View for the Add Event button:
struct AddEventButtonView: View {
@Binding var editMode: Bool
@Binding var showModal: Bool
var namespace: Namespace.ID
var body: some View {
Image(systemName: "calendar.badge.plus")
.frame(height: 100)
.frame(maxWidth: .infinity)
.opacity(self.editMode ? 0.0 : 1.0)
.onTapGesture {
withAnimation {
self.showModal = true
}
}
}
}
and this is my modal view:
struct AddEventView: View {
@State var eventName: String = ""
@State var endDate = Date()
@State var gradientIndex: Int = 0
@Binding var showModal: Bool
@Binding var events: [Event]
var namespace: Namespace.ID
init(namespace: Namespace.ID, events: Binding<[Event]>, showModal: Binding<Bool>) {
self.namespace = namespace
self._events = events
self._showModal = showModal
}
var body: some View {
VStack(spacing: 30.0) {
//...
Button(action: {
let event = Event(name: eventName, start: .init(), end: endDate, gradientIndex: gradientIndex)
self.events.append(event)
withAnimation {
self.showModal = false
}
}) {
RoundedRectangle(cornerRadius: 13)
.frame(maxWidth: .infinity)
.frame(height: 42)
.overlay(
Text("Add Event")
.foregroundColor(.white)
.bold()
)
}
.disabled(self.eventName.isEmpty)
}
}
}
If anyone has any idea of how to update the LazyVGrid to show the new event card when a new event is added that'd be awesome, thanks!
Here's the problem: