I think that's to be expected.
The body will be created every time eventListViewModel changed. And the fullScreenCover , you can think it and it's subviews as part of the body.
And I wrote a demo code as below:
class Time: ObservableObject {
@Published var second = 0
init(second: Int = 0) {
self.second = second
}
func start() {
Task {
for _ in 0 ... 999 {
try await Task.sleep(nanoseconds: 1000000000)
second += 1
}
}
}
}
struct ContentView2: View {
@StateObject private var time = Time()
@State private var isPresented = false
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("\(time.second)")
}
.onAppear {
time.start()
}
.onTapGesture {
isPresented = true
}
.padding()
.fullScreenCover(isPresented: $isPresented) {
Text("\((0 ... 1000).randomElement() ?? 0)")
.onTapGesture {
isPresented = false
}
}
}
}
the time will change every one second which will cause ContentView2's body property re-render every one second. fullScreenCover display a Text which shows a random number. if the fullScreenCover is presented, you will see the text changes every one second. So how to avoid this "issue" ?
Here's code:
class Time: ObservableObject {
@Published var second = 0
init(second: Int = 0) {
self.second = second
}
func start() {
Task {
for _ in 0 ... 999 {
try await Task.sleep(nanoseconds: 1000000000)
second += 1
}
}
}
}
struct TimeView: View {
@StateObject private var time = Time()
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("\(time.second)")
}
.onAppear {
time.start()
}
}
}
struct ContentView: View {
@State private var isPresented = false
var body: some View {
TimeView()
.onTapGesture {
isPresented = true
}
.padding()
.fullScreenCover(isPresented: $isPresented) {
Text("\((0 ... 1000).randomElement() ?? 0)")
.onTapGesture {
isPresented = false
}
}
}
}
Extract the view with timer into a new view will solve the issue.