Render SwiftUI view modifiers on Android#9
Merged
Conversation
Previously ModifiedContent's AndroidPrimitive conformance was incomplete: it unconditionally flattened to the unmodified content, silently discarding any modifier's effect. Wire up a proper dispatcher that applies AndroidViewModifier conformances imperatively and reproduces the view-tree expansion of the background/overlay modifiers that actually build a distinct view tree.
…yout Adds AndroidCompositingContainer, a self-mounting FrameLayout host that creates and attaches its children's native views imperatively rather than exposing them through ParentView/reconciler diffing — necessary because this container is often reached via an outer view modifier's own resolution path, which bypasses the reconciler entirely.
Color previously had no direct Android renderer (its Body was a shape-view composite with no native backing), so it couldn't be used as bare content — needed for compositing it behind/over other views for backgrounds/overlays.
Only rounded-rect and plain-rect shapes are handled — the by-far dominant real-world usage — via a GradientDrawable outline and setClipToOutline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
View modifiers previously had no effect on Android.
ModifiedContent'sAndroidPrimitiveconformance was incomplete — it unconditionally flattened to the unmodified content, silently discarding every modifier. Only.opacity()worked, via a separate self-contained mechanism that never went through this path.This wires up a real dispatcher and adds per-modifier conformances for the core layout and effect modifiers.
What's included
ModifiedContentdispatcher — appliesAndroidViewModifierconformances imperatively to the resolved native view, and reproduces the view-tree expansion for the background/overlay modifiers that genuinely build a distinct tree.AndroidCompositingContainer— a self-mountingFrameLayouthost backing.background()/.overlay(). It creates and attaches children imperatively rather than viaParentView/reconciler diffing, because it's frequently reached through an outer modifier's own resolution path, which bypasses the reconciler entirely. Built to be reused forZStack.Coloras a native view —Colorhad no direct renderer (itsBodywas a shape-view composite with no native backing), so it couldn't be used as bare content for compositing..padding(),.frame(),.offset(),.rotationEffect(),.scaleEffect(),.clipShape()/.cornerRadius().ModifierScreenexercising each modifier individually.Notes
.background(Color.x)resolves to_BackgroundStyleModifier, not_BackgroundModifier— Swift picks the more specificShapeStyle-constrained overload sinceColorconforms to both. Only solidColorstyles render; gradients and materials need aShape-backed renderer that doesn't exist yet, so they're skipped rather than rendered wrong..foregroundColoris not included — it has no dedicated modifier struct upstream and needs an environment-read hook inAndroidTextinstead.Verification
All seven sections of the new gallery screen confirmed rendering correctly on the emulator: padding, frame, background, clip + corner radius, offset, rotation, and scale.