UIHostingConfiguration on tvOS: focus permanently broken with multiple focusable SwiftUI views
Hi everyone,
I'm working on a tvOS app with a UICollectionView. Some cells embed SwiftUI content via UIHostingConfiguration, specifically a row of 3 buttons that should be individually focusable. The cell itself returns canBecomeFocused = false so focus passes through to the SwiftUI buttons.
The problem: after navigating focus into that section once, it becomes permanently unfocusable. Focus enters briefly, then immediately exits to nil on its own, without any user input. From that point on, the focus engine completely skips the section.
The exact same SwiftUI view works perfectly when embedded via UIHostingController instead.
How to reproduce
Press DOWN to move focus into the UIHostingConfiguration section
Focus lands on a SwiftUI button for a split second
Focus exits on its own and bumps to another section
The section is now dead, focus skips it on every subsequent navigation
What the system logs say (-UIFocusLoggingEnabled YES)
Right when focus enters, the system reports the SwiftUI focus items as "disappearing":
Ignoring focus update request for disappearing focus environment <UIKitFocusSectionResponderItem>
Then when searching for a new focusable item:
<SwiftUI._UIInheritedView> → (warning) No focusable items found.
<UIHostingContentView> → (warning) No focusable items found.
=== unable to find focused item in context. retrying with updated request. ===
The views are still in the hierarchy (verified by pointer), but the UIHostingContentView no longer exposes its virtual focus items. I also see mismatched parentFocusEnvironment on those items, pointing to a _UIHostingView from a completely different cell.
What I've tried
I've spent a lot of time on this with my colleagues, dug through the very limited documentation available online, and even used AI agents to help brainstorm. We tested 10 different approaches, none worked:
Overriding preferredFocusEnvironments to point to the UIHostingContentView
setNeedsFocusUpdate() / updateFocusIfNeeded(), rescan finds nothing
Forcing UIKit redraws (setNeedsLayout, setNeedsDisplay)
Removing .focusSection()
Removing all SwiftUI animations, identical behavior
Using canFocusItemAt: delegate instead of cell subclass, identical
remembersLastFocusedIndexPath = true, causes a separate focus trap
configurationUpdateHandler + setNeedsUpdateConfiguration(), config is rebuilt but virtual items stay deregistered
Verified the UIHostingContentView never leaves the hierarchy. It doesn't, its internal state is just corrupted
My workaround
I switched to UIHostingController with proper view controller containment. It works because the hosting controller is a full UIFocusEnvironment, so the focus engine can traverse it and it correctly maintains its virtual items.
Has anyone encountered this? Is there a known pattern for using UIHostingConfiguration on tvOS with multiple focusable SwiftUI elements? Or should I just file a Feedback?
Thanks for any help!
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Created
UIHostingConfiguration on tvOS: focus permanently broken with multiple focusable SwiftUI views
Hi everyone,
I'm working on a tvOS app with a UICollectionView. Some cells embed SwiftUI content via UIHostingConfiguration, specifically a row of 3 buttons that should be individually focusable. The cell itself returns canBecomeFocused = false so focus passes through to the SwiftUI buttons.
The problem: after navigating focus into that section once, it becomes permanently unfocusable. Focus enters briefly, then immediately exits to nil on its own, without any user input. From that point on, the focus engine completely skips the section.
The exact same SwiftUI view works perfectly when embedded via UIHostingController instead.
How to reproduce
Press DOWN to move focus into the UIHostingConfiguration section
Focus lands on a SwiftUI button for a split second
Focus exits on its own and bumps to another section
The section is now dead, focus skips it on every subsequent navigation
What the system logs say (-UIFocusLoggingEnabled YES)
Right when focus enters, the system reports the SwiftUI focus items as "disappearing":
Ignoring focus update request for disappearing focus environment <UIKitFocusSectionResponderItem>
Then when searching for a new focusable item:
<SwiftUI._UIInheritedView> → (warning) No focusable items found.
<UIHostingContentView> → (warning) No focusable items found.
=== unable to find focused item in context. retrying with updated request. ===
The views are still in the hierarchy (verified by pointer), but the UIHostingContentView no longer exposes its virtual focus items. I also see mismatched parentFocusEnvironment on those items, pointing to a _UIHostingView from a completely different cell.
What I've tried
I've spent a lot of time on this with my colleagues, dug through the very limited documentation available online, and even used AI agents to help brainstorm. We tested 10 different approaches, none worked:
Overriding preferredFocusEnvironments to point to the UIHostingContentView
setNeedsFocusUpdate() / updateFocusIfNeeded(), rescan finds nothing
Forcing UIKit redraws (setNeedsLayout, setNeedsDisplay)
Removing .focusSection()
Removing all SwiftUI animations, identical behavior
Using canFocusItemAt: delegate instead of cell subclass, identical
remembersLastFocusedIndexPath = true, causes a separate focus trap
configurationUpdateHandler + setNeedsUpdateConfiguration(), config is rebuilt but virtual items stay deregistered
Verified the UIHostingContentView never leaves the hierarchy. It doesn't, its internal state is just corrupted
My workaround
I switched to UIHostingController with proper view controller containment. It works because the hosting controller is a full UIFocusEnvironment, so the focus engine can traverse it and it correctly maintains its virtual items.
Has anyone encountered this? Is there a known pattern for using UIHostingConfiguration on tvOS with multiple focusable SwiftUI elements? Or should I just file a Feedback?
Thanks for any help!
You can find the code here : https://github.com/ThomasDutartre/focus-problem-tvos
I recored the problem here :
https://youtu.be/yPfM5AvU2ko