There is a pretty classic scenario when the view was shown and you send view shown event to some analytics platform.
How do I detect if the first view appeared after the second one was closed?
var body: some View {
Button("Show second") {
isSecondViewShown.toggle()
}
.onAppear {
print("First appeared")
}
.fullScreenCover(isPresented: $isSecondViewShown) {
Button("Close second") {
isSecondViewShown.toggle()
}
.onAppear {
print("Second appeared")
}
}
}
onAppear
(which feels natural) does not work in this case. When you tap "Show Second" button and then "Close Second" button the following will be printed in logs:
First appeared
Second appeared
Instead of:
First appeared
Second appeared
First appeared
You can of course observe isSecondViewShown
but it’s not reliable and misleading.
4
Answers
Maybe you need to be more specific on your conditions, because as stated, while it’s hard to know when the first view is shown, it’s easy to know when the second view is closed (and the first view is then shown again). So the very simple thing to do is to watch when
isSecondViewShown
flips fromtrue
tofalse
, meaning it’s no longer shown:Another option is a bit more involved: force
onAppear
on the view by having it in a container that has to redraw as a result of second view disappearance. This is by using an.id
modifier:So the above will cause:
As you can see I didn’t solve your actual issue: how to find out that the view is displayed (both solutions rely on second view disappearance instead). So these are workarounds really
Instead of using
.fullScreenCover(isPresented:)
you can use.fullScreenCover(item:)
by changingisSecondViewShown
to an optional, you can use that. Here is the code I used:And here is the
SecondScreen
struct:And this usage can be modified and used in other ways like putting it in a array to make multi-pages.
onAppear
refers to the underlyingUIView
. Since you are usingfullScreenCover
theUIButton
wasn’t removed, thus never disappeared, so the output is correct.The reason that the
First appeared
is not being printed the second time is because the.fullScreenCover
acts like a sheet. Therefore, the first view has not actually disappeared yet.The first solution is through the use of
onDisappear
on the.fullScreenCover
button. However, this means it’s not checking whether the first view is coming into view, but if the second one has fully left the view. Like so:The second solution is a bit more work but allows you to have multiple pages working on the same view. But… there is no
.fullScreenCover
animation. This can be done like so:Where
ViewTypes
is:Through the use of
withAnimation
however, you can achieve custom animations to fit your needs. Hope this helps!