diff --git a/Sources/OpenSwiftUI/Animation/Timeline/AlwaysOnBridge.swift b/Sources/OpenSwiftUI/Animation/Timeline/AlwaysOnBridge.swift index 73dd5c2c0..f3782d047 100644 --- a/Sources/OpenSwiftUI/Animation/Timeline/AlwaysOnBridge.swift +++ b/Sources/OpenSwiftUI/Animation/Timeline/AlwaysOnBridge.swift @@ -181,7 +181,6 @@ struct OpenSwiftUITextAlwaysOnProvider: TextAlwaysOnProvider { schedule: @autoclosure () -> Attribute<(any TimelineSchedule)?>, outputs: inout _ViewOutputs ) { - guard _UIAlwaysOnEnvironment._alwaysOnSupported else { return } diff --git a/Sources/OpenSwiftUI/Integration/Graphic/UIKit/UIKitConversions.swift b/Sources/OpenSwiftUI/Integration/Graphic/UIKit/UIKitConversions.swift index 2e2a1a2ac..4d354557f 100644 --- a/Sources/OpenSwiftUI/Integration/Graphic/UIKit/UIKitConversions.swift +++ b/Sources/OpenSwiftUI/Integration/Graphic/UIKit/UIKitConversions.swift @@ -235,4 +235,25 @@ extension UITraitEnvironmentLayoutDirection { } } +// MARK: - UIUserInterfaceIdiom Conversions + +extension UIUserInterfaceIdiom { + package var idiom: AnyInterfaceIdiom? { + switch self { + case .phone: AnyInterfaceIdiom(.phone) + case .pad: AnyInterfaceIdiom(.pad) + case .tv: AnyInterfaceIdiom(.tv) + case .carPlay: AnyInterfaceIdiom(.carPlay) + case .watch: AnyInterfaceIdiom(.watch) + case .mac: AnyInterfaceIdiom(.mac) + case .vision: AnyInterfaceIdiom(.vision) + default: nil + } + } +} + +extension UIUserInterfaceIdiom { + static let watch = UIUserInterfaceIdiom(rawValue: 4)! +} + #endif diff --git a/Sources/OpenSwiftUI/Integration/Hosting/UIKit/View/UIHostingView.swift b/Sources/OpenSwiftUI/Integration/Hosting/UIKit/View/UIHostingView.swift index 3cb7a94c5..8edc6e873 100644 --- a/Sources/OpenSwiftUI/Integration/Hosting/UIKit/View/UIHostingView.swift +++ b/Sources/OpenSwiftUI/Integration/Hosting/UIKit/View/UIHostingView.swift @@ -7,13 +7,13 @@ // ID: FAF0B683EB49BE9BABC9009857940A1E (SwiftUI) #if os(iOS) || os(visionOS) +public import UIKit +import OpenAttributeGraphShims @_spi(ForOpenSwiftUIOnly) @_spi(Private) public import OpenSwiftUICore -public import UIKit -import OpenSwiftUI_SPI - import OpenSwiftUISymbolDualTestsSupport +import OpenSwiftUI_SPI /// A UIView which hosts an OpenSwiftUI View hierarchy. @available(macOS, unavailable) @@ -143,7 +143,9 @@ open class _UIHostingView: UIView, XcodeViewDebugDataProvider where Con // AccessibilityFocus.changed(from: nil, to: nil, within: self) } } - + + // private weak var delegate: UIHostingViewDelegate? + required public init(rootView: Content) { _rootView = rootView Update.begin() @@ -167,6 +169,7 @@ open class _UIHostingView: UIView, XcodeViewDebugDataProvider where Con } // TODO super.init(frame: .zero) + _base.viewGraph.append(feature: HostViewGraph(host: self)) // TODO let base = base if let host = base.host { @@ -718,4 +721,33 @@ extension _UIHostingView: UIViewControllerProvider { } } +// MARK: _UIHostingView.HostViewGraph [6.5.4] [Blocked by Gesture System] + +extension _UIHostingView { + private struct HostViewGraph: ViewGraphFeature { + weak var host: _UIHostingView? + + func modifyViewInputs(inputs: inout _ViewInputs, graph: ViewGraph) { + guard let host else { + return + } + // inputs.eventBindingBridgeFactory = UIKitResponderEventBindingBridge.Factory.self + // inputs.gestureContainerFactory = UIKitGestureContainerFactory.self + // host.delegate?.xx + var idiom = inputs[InterfaceIdiomInput.self] + if idiom == nil { + Update.syncMain { + idiom = host.traitCollection.userInterfaceIdiom.idiom ?? UIDevice.current.userInterfaceIdiom.idiom + } + } + idiom.map { inputs[InterfaceIdiomInput.self] = $0 } + let box: WeakBox = WeakBox(host) + let boxAttr = Attribute(value: box) + // inputs[UIKitHostContainerFocusItemInput.self] = boxAttr + inputs.textAlwaysOnProvider = OpenSwiftUITextAlwaysOnProvider.self + // navigationBridge?.updateViewInputs(&inputs) + } + } +} + #endif diff --git a/Sources/OpenSwiftUICore/Event/Event/EventBindingSource.swift b/Sources/OpenSwiftUICore/Event/Event/EventBindingSource.swift index 68f633186..fb4faabd2 100644 --- a/Sources/OpenSwiftUICore/Event/Event/EventBindingSource.swift +++ b/Sources/OpenSwiftUICore/Event/Event/EventBindingSource.swift @@ -65,11 +65,17 @@ package struct EventBindingBridgeFactoryInput: ViewInput { } extension _ViewInputs { + @inline(__always) + package var eventBindingBridgeFactory: (any EventBindingBridgeFactory.Type)? { + get { self[EventBindingBridgeFactoryInput.self] } + set { self[EventBindingBridgeFactoryInput.self] = newValue } + } + package func makeEventBindingBridge( bindingManager: EventBindingManager, responder: any AnyGestureResponder ) -> any EventBindingBridge & GestureGraphDelegate { - guard let factory = self[EventBindingBridgeFactoryInput.self] else { + guard let factory = eventBindingBridgeFactory else { preconditionFailure("Event binding factory must be configured") } return factory.makeEventBindingBridge( diff --git a/Sources/OpenSwiftUICore/Event/Gesture/GestureContainerFactory.swift b/Sources/OpenSwiftUICore/Event/Gesture/GestureContainerFactory.swift index e54e71ee3..bfaa19be9 100644 --- a/Sources/OpenSwiftUICore/Event/Gesture/GestureContainerFactory.swift +++ b/Sources/OpenSwiftUICore/Event/Gesture/GestureContainerFactory.swift @@ -2,9 +2,10 @@ // GestureContainerFactory.swift // OpenSwiftUICore // +// Audited for 6.5.4 // Status: Complete -// MARK: - GestureContainerFactory [6.5.4] +// MARK: - GestureContainerFactory package protocol GestureContainerFactory { static func makeGestureContainer(responder: any AnyGestureContainingResponder) -> AnyObject @@ -17,8 +18,14 @@ package struct GestureContainerFactoryInput: ViewInput { } extension _ViewInputs { + @inline(__always) + package var gestureContainerFactory: (any GestureContainerFactory.Type)? { + get { self[GestureContainerFactoryInput.self] } + set { self[GestureContainerFactoryInput.self] = newValue } + } + package func makeGestureContainer(responder: any AnyGestureContainingResponder) -> AnyObject { - guard let factory = self[GestureContainerFactoryInput.self] else { + guard let factory = gestureContainerFactory else { preconditionFailure("Gesture container factory must be configured") } return factory.makeGestureContainer(responder: responder)