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

[feat]: add support for sizingOptions to SwiftUIScreen #277

Merged
merged 10 commits into from
Mar 28, 2024

Conversation

n8chur
Copy link
Collaborator

@n8chur n8chur commented Mar 26, 2024

Market's Modal framework relies on preferredContentSize to size modals during presentation.

Without any changes, view controllers that back SwiftUIScreens never had their preferredContentSize updated.

SwiftUIScreen is backed by a UIHostingController subclass. In iOS 16 and above, a new sizingOption parameter was added that allows a consumer to specify the .preferredContentSize option which will cause the view controller to update the preferredContentSize as it changes over time. Before iOS 16, you have to do this manually.

One thing that's surprising is that with the sizingOption support for preferredContentSize, the preferredContentSize does not appear to be updated after the first layout. Also, the UIHostingController's view is does not appear to have setNeedsLayout set, which has generally been expected in Market's infrastructure so far. I've opened UI-5797 to investigate this to see whether Market's Modal framework is holding this wrong, or if the workarounds found in this PR are in fact needed.

Market also supports having the preferredContentSize automatically calculated if it's requested by a consumer via an associated value on UIViewController—we'll likely want to figure out a way to support this with SwiftUIScreens, and that may involve moving some of that infra into the Workflow repo (UI-5801).

I've also introduced a test target for WorkflowSwiftUIExperimental so that I could add some tests related to preferredContentSize calculations.

An integration experiment was added to Market in here.

These changes resolve UI-5766.

Checklist

  • Unit Tests
  • UI Tests
  • Snapshot Tests (iOS only)
  • I have made corresponding changes to the documentation

@n8chur n8chur changed the title [DNR WIP] feat(ios): add support for sizingOptions to SwiftUIScreen [DNR WIP] [feat]: add support for sizingOptions to SwiftUIScreen Mar 26, 2024
@n8chur n8chur changed the title [DNR WIP] [feat]: add support for sizingOptions to SwiftUIScreen [feat]: add support for sizingOptions to SwiftUIScreen Mar 27, 2024
@n8chur n8chur marked this pull request as ready for review March 27, 2024 19:22
@n8chur n8chur requested review from a team as code owners March 27, 2024 19:22
setNeedsLayoutBeforeFirstLayoutIfNeeded()
}

override func viewDidLayoutSubviews() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Market also supports having the preferredContentSize automatically calculated if it's requested by a consumer via an associated value on UIViewController—we'll likely want to figure out a way to support this with SwiftUIScreens, and that may involve moving some of that infra into the Workflow repo (UI-5801).

Hmm yeah this is an interesting one, since that stuff all lives in Modals right now. We'll definitely want to keep it, since avoiding the duplicative preferredContentSize calculations was a pretty big performance win.

Trying to think if there's a way we could flow this into the SwiftUI environment at the Market layer... But I guess since this is a view controller, we don't have that available.

One gross idea, but it would work, is do a respondsToSelector check on the associated value we added, and reference it via valueForKey in this repo. Icky but it would do the thing we want...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may want to consider moving that associated object to a ViewEnvironmentKey, and then move that key's definition to ViewEnvironmentUI, possibly also adding support for this automatically in WorkflowUI (along with here).

Let's move further discussion on this to UI-5801 so that the context is easier to discover once we start that work!

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .clear
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious: is this new and necessary for the PCS behavior we want?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, whoops, meant to call this out or pull it into a separate PR...

It's not necessary to achieve the goal of this PR, but IMO it's generally expected, and annoying to work around if you want to have a transparent background when working with Screens like this. We also set this in WorkflowHostingController.

Epoxy sets this on their hosting controller and they included a comment describing their motivation:

    // A `UIHostingController` has a system background color by default as it's typically used in
    // full-screen use cases. Since we're using this view controller to place SwiftUI views within
    // other view controllers we default the background color to clear so we can see the views
    // below, e.g. to draw highlight states in a `CollectionView`.

Happy to move this to a separate PR if we'd prefer!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explaining. Makes sense to me, and not important to break out IMO 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's worth cribbing that comment into our implementation too.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth adding a similar comment here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth adding a similar comment here?

Eh, maybe? I think it's probably pretty self-explanatory.
Happy to add one if anyone feels strongly though!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's worth cribbing that comment into our implementation too.

2 comments about it seems like a signal that I should add the comment—I'll do so in a follow up!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@n8chur
Copy link
Collaborator Author

n8chur commented Mar 28, 2024

Merging now that I have 2 stamps but more than happy to follow up with additional changes if requested!

@n8chur n8chur merged commit 14ffc04 into main Mar 28, 2024
13 checks passed
@n8chur n8chur deleted the westin/workflowswiftuiexperimental/pcs-support branch March 28, 2024 19:03
override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .clear
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's worth cribbing that comment into our implementation too.

Copy link

@nsillik nsillik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

surprisingly straightforward, LGTM!

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.

6 participants