Skip to content

Use ImageRenderer for ideal size layout on iOS 16+#1071

Open
abrahamduran wants to merge 3 commits intopointfreeco:mainfrom
abrahamduran:fix/sizethatfits-imagerenderer
Open

Use ImageRenderer for ideal size layout on iOS 16+#1071
abrahamduran wants to merge 3 commits intopointfreeco:mainfrom
abrahamduran:fix/sizethatfits-imagerenderer

Conversation

@abrahamduran
Copy link
Copy Markdown

Fixes #1070

Summary

.sizeThatFits is broken on modern iOS simulators. UIHostingController.sizeThatFits(in: .zero) returns the view's minimum compressed size instead of its ideal size, causing truncated text and collapsed layouts.

The root cause: CGSize cannot express "unspecified" dimensions. SwiftUI's ProposedViewSize supports nil (meaning "use your ideal size"), but there's no CGSize equivalent — so there's no value you can pass to UIHostingController.sizeThatFits(in:) that means "ideal size."

Changes

SwiftUIView.swift — For .sizeThatFits on iOS 16+, use ImageRenderer with ProposedViewSize(width: nil, height: nil) instead of the UIHostingControllerUIWindowlayer.render pipeline. This is the SwiftUI-native way to ask for ideal size.

  • ImageRenderer bypasses UIKit's trait system, so UITraitCollection.userInterfaceStyle is converted to SwiftUI's .colorScheme environment
  • MainActor.assumeIsolated is used because ImageRenderer is @MainActor-isolated but the asyncPullback closure is nonisolated (snapshot tests always run on main thread)
  • .device and .fixed layouts are unchanged — they still use the UIHostingController/UIWindow path

iOS 13-15 fallback — Uses screen width with unconstrained height as a reasonable heuristic, since ImageRenderer isn't available.

Tests — Two new tests that expose the bug:

  • testSwiftUIView_sizeThatFits_paddingText with .padding() (padding collapses with the old path)
  • testSwiftUIView_sizeThatFits_spacerHStack with Spacer() (spacer gets crushed to zero with the old path)

Note on baselines

The testSwiftUIView_iOS.size-that-fits.png baseline was re-recorded with the new ImageRenderer path. The new test baselines were recorded on an iPhone 17 simulator (@3x) — they may need re-recording on your CI's pinned simulator.

- Use ImageRenderer (iOS 16+) with ProposedViewSize(nil, nil) to get ideal size
- Fall back to screen-width proposal for iOS 13-15
- Add tests for padding and Spacer views that expose the bug
@abrahamduran abrahamduran force-pushed the fix/sizethatfits-imagerenderer branch from db67873 to 0a51132 Compare March 21, 2026 03:28
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.

.sizeThatFits renders SwiftUI views at minimum compressed size instead of ideal size

1 participant