Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-present sheet, popover and fullscreen when identity changes. #77

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

tgrapperon
Copy link
Contributor

@tgrapperon tgrapperon commented Jan 31, 2023

EDIT: I made a booboo and the branch of #76 was deleted and the PR closed, so I'm opening the same PR again with a new branch.

This is a WIP PR that implement a solution to #75.
I still need to implement the confirmation dialog part and fix existential opening on older versions of Swift. A few remarks:

  • sheet modifiers were annotated @MainActor, but .popover and .fullScreenCover weren't, so I removed this annotation for .sheet. I can implement the other alternative if needed.
  • I removed the Team ID from the Standups example.
  • Fact's id from CaseStudies is now only based on the number instead of the number + the description to avoid unwanted presentations when the description is updated.[Edit, I need to fix the saved facts list too]

@tgrapperon tgrapperon marked this pull request as draft January 31, 2023 20:19
@tgrapperon
Copy link
Contributor Author

I don't know if alert and confirmationDialog should follow the same treatment. According to my tests, SwiftUI doesn't represent the alert/dialog if the presenting value changes, and any interaction with a button closes the alert/dialog.

With the current implementation, .sheet, .fullScreenCover and .popover are re-presented if the presentation identity changes. This presentation identity is:

  • The id: ID value if the presented value is Identifiable.
  • The value's type otherwise, annotated with the enum's case tag if it applies.

I'm not really sure if we should use the enum's case tag for optionals. The PR can be easily modified to only tag non-optional enums and let the optionality be handled by the binding upstream.

The issue with the current implementation is that there is no built-in way to opt-out of this behavior, and I'm not really sure how to implement one without touching the API or adding a new protocol. One workaround would be to wrap the presented value in an Identifiable wrapper that returns a constant id (but I don't think such wrapper should ship with the library).

@tgrapperon tgrapperon marked this pull request as ready for review February 1, 2023 12:49
@stephencelis
Copy link
Member

@tgrapperon Thanks for looking into this! I won't have time to look right away, but did want to let you know that we encountered the following issue when exploring this in TCA the other day:

https://gist.github.com/mbrandonw/f8b94957031160336cac6898a919cbb7#file-fb11975674-md

Basically, re-presenting a sheet causes dismissal hooks to fail, and we need to use onDisappear on the sheet content to workaround.

There is even more puzzling behavior with popovers, where dismissal fires for the re-presented popover before it's even initially presented. We haven't found workarounds for this yet, if there are any.

We haven't checked full screen covers...hopefully they're free of SwiftUI bugs... 😬

@Muhammed9991
Copy link

Is this still being worked on?

@dlewandaDK
Copy link

Following up here, my team would benefit from this fix becoming part of the product. We are maintaining a local implementation that is similar to this one, but would much rather lean on a first-party solution that has broader acceptance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants