Summary
Toggle can render its backing platform switch outside the visible content area when using the OpenSwiftUI View Renderer.
The same view renders correctly with SwiftUI, but under OSUI the UISwitch exists in the UIKit hierarchy while it is not visible in the expected location.
Reproduction
Use a minimal Toggle label that contains a large content view:
struct ToggleExample: View {
@State private var toggle = true
var body: some View {
Toggle(isOn: $toggle) {
Color.red
}
}
}
Run the example with the OpenSwiftUI View Renderer enabled.
Expected Behavior
The switch should be visible and positioned the same way as the SwiftUI-backed rendering path.
Actual Behavior
The red content renders, but the switch is not visible in the expected position. Inspecting the UIKit hierarchy shows the platform switch exists, but it is placed under an inherited wrapper and offset outside the visible content area.
The observed hierarchy shape differs from SwiftUI:
- SwiftUI places
PlatformViewHost<Switch> directly under the hosting view.
- OSUI places
PlatformViewHost<Switch> under _UIInheritedView, and the platform view position is effectively applied relative to that wrapper.
This causes the switch to be present but visually misplaced.
Notes
A compatibility fix is proposed in #875.
Log
OpenSwiftUI ViewRenderer
(lldb) po [0x105f16830 recursiveDescription]
<_TtGC11OpenSwiftUI14_UIHostingViewGV15OpenSwiftUICore15ModifiedContentVS1_7AnyViewVS_12RootModifier__: 0x105f16830; frame = (0 0; 402 874); autoresize = W+H; backgroundColor = <UIDynamicSystemColor: 0x60000173ab40; name = systemBackgroundColor>; layer = <OpenSwiftUI.UIHostingViewDebugLayer: 0x600000248d60>>
| <OpenSwiftUI._UIGraphicsView: 0x10881d5d0; frame = (0 62; 345 778); anchorPoint = (0, 0); autoresizesSubviews = NO; backgroundColor = UIExtendedSRGBColorSpace 1 0.231373 0.188235 1; layer = <CALayer: 0x600000250680>>
| <OpenSwiftUI._UIInheritedView: 0x10881dd10; frame = (353 435.667; 49 31); anchorPoint = (0, 0); autoresizesSubviews = NO; layer = <CALayer: 0x600000250880>>
| | <_TtGC11OpenSwiftUI16PlatformViewHostGVS_P10$109c4754c32PlatformViewRepresentableAdaptorVS_P10$109c4c72c6Switch__: 0x10881b660; baseClass = _UIConstraintBasedLayoutHostingView; frame = (353 435.667; 49 31); anchorPoint = (0, 0); layer = <CALayer: 0x600000250180>>
| | | <UISwitch: 0x105d08380; frame = (0 0; 51 31); autoresize = W+H; gestureRecognizers = <NSArray: 0x600000010860>; layer = <CALayer: 0x60000024f180>>
| | | | <UISwitchModernVisualElement: 0x105d11c00; frame = (0 0; 51 31); gestureRecognizers = <NSArray: 0x6000002050c0>; layer = <CALayer: 0x60000024f200>>
| | | | | <UIView: 0x1088168a0; frame = (0 0; 51 31); backgroundColor = <UIDynamicSystemColor: 0x600001717040; name = _switchOffColor>; layer = <CALayer: 0x600000247e20>>
| | | | | <UIView: 0x108816720; frame = (0 0; 51 31); layer = <CALayer: 0x600000247de0>>
| | | | | | <UIImageView: 0x1088114c0; frame = (-459 0; 510 31); hidden = YES; opaque = NO; userInteractionEnabled = NO; image = <UIImage:0x60000300d320 CGImage anonymous; (510 1)@3>; layer = <CALayer: 0x600000244c20>>
| | | | | | <UIView: 0x10881b020; frame = (0 0; 51 31); layer = <CALayer: 0x600000250020>>
| | | | | | | <UIImageView: 0x10881ac60; frame = (38.6667 16; 0 0); userInteractionEnabled = NO; tintColor = <UIDynamicSystemColor: 0x600001715e40; name = _switchOffImageColor>; image = <(null):0x0 (null) anonymous; (0 0)@0>; layer = <CALayer: 0x600000242220>>
| | | | | | | <UIImageView: 0x10881ae40; frame = (12 16; 0 0); alpha = 0; userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 1 1; image = <(null):0x0 (null) anonymous; (0 0)@0>; layer = <CALayer: 0x600000247f80>>
| | | | | | <UIImageView: 0x108816d90; frame = (-6 -3; 43 43); opaque = NO; userInteractionEnabled = NO; image = <_UIResizableImage:0x600003b12760 CGImage anonymous; (43 43)@3>; layer = <CALayer: 0x600000219880>>
SwiftUI View Renderer
(lldb) po [0x104215990 recursiveDescription]
<_TtGC11OpenSwiftUI14_UIHostingViewGV15OpenSwiftUICore15ModifiedContentVS1_7AnyViewVS_12RootModifier__: 0x104215990; frame = (0 0; 402 874); autoresize = W+H; backgroundColor = <UIDynamicSystemColor: 0x600001720640; name = systemBackgroundColor>; layer = <OpenSwiftUI.UIHostingViewDebugLayer: 0x6000002373e0>>
| <OpenSwiftUI._UIGraphicsView: 0x10431b9c0; frame = (0 62; 345 778); anchorPoint = (0, 0); autoresizesSubviews = NO; backgroundColor = UIExtendedSRGBColorSpace 1 0.231373 0.188235 1; layer = <CALayer: 0x60000023ae80>>
| <_TtGC11OpenSwiftUI16PlatformViewHostGVS_P10$107ef80d832PlatformViewRepresentableAdaptorVS_P10$107efd2ac6Switch__: 0x10430e780; baseClass = _UIConstraintBasedLayoutHostingView; frame = (353 435.667; 49 31); anchorPoint = (0, 0); layer = <CALayer: 0x60000023ab00>>
| | <UISwitch: 0x10440bd50; frame = (0 0; 51 31); autoresize = W+H; gestureRecognizers = <NSArray: 0x60000000d0b0>; layer = <CALayer: 0x600000233ae0>>
| | | <UISwitchModernVisualElement: 0x10440e170; frame = (0 0; 51 31); gestureRecognizers = <NSArray: 0x60000023a560>; layer = <CALayer: 0x600000233b60>>
| | | | <UIView: 0x104416cf0; frame = (0 0; 51 31); backgroundColor = <UIDynamicSystemColor: 0x600001728900; name = _switchOffColor>; layer = <CALayer: 0x60000023cbe0>>
| | | | <UIView: 0x104416b70; frame = (0 0; 51 31); backgroundColor = <UIDynamicCatalogSystemColor: 0x60000170ff40; name = systemGreenColor>; layer = <CALayer: 0x60000023cba0>>
| | | | | <UIImageView: 0x104411bd0; frame = (0 0; 510 31); hidden = YES; opaque = NO; userInteractionEnabled = NO; image = <UIImage:0x6000030093b0 CGImage anonymous; (510 1)@3>; layer = <CALayer: 0x60000023c640>>
| | | | | <UIView: 0x1043178f0; frame = (0 0; 51 31); layer = <CALayer: 0x60000023a9a0>>
| | | | | | <UIImageView: 0x10430fe50; frame = (38.6667 16; 0 0); alpha = 0; userInteractionEnabled = NO; tintColor = <UIDynamicSystemColor: 0x600001720f00; name = _switchOffImageColor>; image = <(null):0x0 (null) anonymous; (0 0)@0>; layer = <CALayer: 0x60000023a840>>
| | | | | | <UIImageView: 0x104310030; frame = (12 16; 0 0); userInteractionEnabled = NO; tintColor = UIExtendedGrayColorSpace 1 1; image = <(null):0x0 (null) anonymous; (0 0)@0>; layer = <CALayer: 0x60000023a900>>
| | | | | <UIImageView: 0x104309740; frame = (14 -3; 43 43); opaque = NO; userInteractionEnabled = NO; image = <_UIResizableImage:0x600003b1c1c0 CGImage anonymous; (43 43)@3>; layer = <CALayer: 0x6000002385c0>>
Summary
Togglecan render its backing platform switch outside the visible content area when using the OpenSwiftUI View Renderer.The same view renders correctly with SwiftUI, but under OSUI the
UISwitchexists in the UIKit hierarchy while it is not visible in the expected location.Reproduction
Use a minimal
Togglelabel that contains a large content view:Run the example with the OpenSwiftUI View Renderer enabled.
Expected Behavior
The switch should be visible and positioned the same way as the SwiftUI-backed rendering path.
Actual Behavior
The red content renders, but the switch is not visible in the expected position. Inspecting the UIKit hierarchy shows the platform switch exists, but it is placed under an inherited wrapper and offset outside the visible content area.
The observed hierarchy shape differs from SwiftUI:
PlatformViewHost<Switch>directly under the hosting view.PlatformViewHost<Switch>under_UIInheritedView, and the platform view position is effectively applied relative to that wrapper.This causes the switch to be present but visually misplaced.
Notes
A compatibility fix is proposed in #875.
Log
OpenSwiftUI ViewRenderer
SwiftUI View Renderer