-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #187 from OpenSwiftUIProject/feature/hosting
Update UIHosting implementation to fix HostingExample example
- Loading branch information
Showing
42 changed files
with
1,616 additions
and
570 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// | ||
// OpenSwiftUIGlue.swift | ||
// OpenSwiftUI | ||
// | ||
// Audited for iOS 18.0 | ||
// Status: Empty | ||
|
||
@_spi(ForOpenSwiftUIOnly) | ||
import OpenSwiftUICore | ||
|
||
#if canImport(Darwin) | ||
|
||
@_cdecl("OpenSwiftUIGlueClass") | ||
func OpenSwiftUIGlueClass() -> CoreGlue.Type { | ||
OpenSwiftUIGlue.self | ||
} | ||
|
||
final class OpenSwiftUIGlue: CoreGlue { | ||
override func makeDefaultLayoutComputer() -> MakeDefaultLayoutComputerResult { | ||
MakeDefaultLayoutComputerResult(value: ViewGraph.current.$defaultLayoutComputer) | ||
} | ||
} | ||
|
||
#endif |
44 changes: 44 additions & 0 deletions
44
Sources/OpenSwiftUI/Integration/Hosting/Platform/HostingViewProtocol.swift
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// | ||
// HostingViewRegistry.swift | ||
// OpenSwiftUI | ||
// | ||
// Audited for iOS 18.0 | ||
// Status: Complete | ||
// ID: 08E507B775941708E73E5FD8531D9361 (SwiftUI) | ||
|
||
@_spi(Private) | ||
public import OpenSwiftUICore | ||
|
||
@_spi(Private) | ||
public protocol HostingViewProtocol: AnyObject { | ||
func preferenceValue<K>(_ key: K.Type) -> K.Value where K: HostPreferenceKey | ||
func convertAnchor<Value>(_ anchor: Anchor<Value>) -> Value | ||
} | ||
|
||
@_spi(Private) | ||
public class HostingViewRegistry { | ||
public static let shared: HostingViewRegistry = HostingViewRegistry() | ||
|
||
public func forEach(_ body: (any HostingViewProtocol) throws -> Void) rethrows { | ||
try elements.values.forEach { box in | ||
guard let element = box.base as? HostingViewProtocol else { | ||
return | ||
} | ||
try body(element) | ||
} | ||
} | ||
|
||
private var elements: [ObjectIdentifier: WeakBox<AnyObject>] = [:] | ||
|
||
func add<V>(_ element: V) where V: HostingViewProtocol { | ||
elements[ObjectIdentifier(element)] = WeakBox(element) | ||
} | ||
|
||
func remove<V>(_ element: V) where V: HostingViewProtocol { | ||
elements.removeValue(forKey: ObjectIdentifier(element)) | ||
} | ||
} | ||
|
||
@_spi(Private) | ||
@available(*, unavailable) | ||
extension HostingViewRegistry: Sendable {} |
39 changes: 39 additions & 0 deletions
39
...ces/OpenSwiftUI/Integration/Hosting/Platform/HostingViewTransparentBackgroundReason.swift
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// HostingViewTransparentBackgroundReason.swift | ||
// OpenSwiftUI | ||
// | ||
// Audited for iOS 18.0 | ||
// Status: Complete | ||
|
||
struct HostingViewTransparentBackgroundReason: OptionSet, CustomStringConvertible { | ||
var rawValue: UInt32 | ||
|
||
static var catalystSidebar = HostingViewTransparentBackgroundReason(rawValue: 1 << 0) | ||
static var catalystPresentation = HostingViewTransparentBackgroundReason(rawValue: 1 << 1) | ||
static var legacyPresentationSPI = HostingViewTransparentBackgroundReason(rawValue: 1 << 2) | ||
static var containerBackground = HostingViewTransparentBackgroundReason(rawValue: 1 << 3) | ||
static var listItemBackground = HostingViewTransparentBackgroundReason(rawValue: 1 << 4) | ||
|
||
var description: String { | ||
var description = "" | ||
if contains(.catalystSidebar) { | ||
description.append("catalystSidebar, ") | ||
} | ||
if contains(.catalystPresentation) { | ||
description.append("catalystPresentation, ") | ||
} | ||
if contains(.legacyPresentationSPI) { | ||
description.append("legacyPresentationSPI, ") | ||
} | ||
if contains(.containerBackground) { | ||
description.append("containerBackground, ") | ||
} | ||
if contains(.listItemBackground) { | ||
description.append("listItemBackground, ") | ||
} | ||
if !description.isEmpty { | ||
description.removeLast(2) | ||
} | ||
return "[\(description)]" | ||
} | ||
} |
15 changes: 0 additions & 15 deletions
15
Sources/OpenSwiftUI/Integration/Hosting/UIKit/AnyUIHostingView.swift
This file was deleted.
Oops, something went wrong.
105 changes: 105 additions & 0 deletions
105
Sources/OpenSwiftUI/Integration/Hosting/UIKit/Controller/UIHostingController.swift
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#if os(iOS) | ||
public import UIKit | ||
|
||
@available(macOS, unavailable) | ||
@available(watchOS, unavailable) | ||
@MainActor | ||
@preconcurrency | ||
open class UIHostingController<Content>: UIViewController where Content : View { | ||
var host: _UIHostingView<Content> | ||
|
||
override open dynamic var keyCommands: [UIKeyCommand]? { | ||
// TODO | ||
nil | ||
} | ||
|
||
public init(rootView: Content) { | ||
// TODO | ||
host = _UIHostingView(rootView: rootView) | ||
super.init(nibName: nil, bundle: nil) | ||
_commonInit() | ||
} | ||
|
||
public init?(coder: NSCoder, rootView: Content) { | ||
// TODO | ||
host = _UIHostingView(rootView: rootView) | ||
super.init(coder: coder) | ||
_commonInit() | ||
} | ||
|
||
public required init?(coder: NSCoder) { | ||
preconditionFailure("init(coder:) must be implemented in a subclass and call super.init(coder:, rootView:)") | ||
} | ||
|
||
func _commonInit() { | ||
host.viewController = self | ||
// toolbar | ||
// toolbar.addPreferences(to: ViewGraph) | ||
// ... | ||
// IsAppleInternalBuild | ||
} | ||
|
||
open override func loadView() { | ||
view = host | ||
} | ||
|
||
public var rootView: Content { | ||
get { host.rootView } | ||
set { host.rootView = newValue } | ||
} | ||
|
||
public var sizingOptions: UIHostingControllerSizingOptions = [] { | ||
didSet { | ||
sizingOptionsDidChange(from: oldValue) | ||
} | ||
} | ||
|
||
@_spi(Private) | ||
public func setRootView(_ newRootView: Content, transaction: Transaction) { | ||
// TODO | ||
} | ||
|
||
public func sizeThatFits(in size: CGSize) -> CGSize { | ||
host.sizeThatFits(size) | ||
} | ||
|
||
public func _render(seconds: Double) { | ||
host.render(interval: seconds, targetTimestamp: nil) | ||
} | ||
|
||
public func _forEachIdentifiedView(body: (_IdentifiedViewProxy) -> Void) { | ||
host._forEachIdentifiedView(body: body) | ||
} | ||
|
||
@available(*, deprecated, message: "Use UIHostingController/safeAreaRegions or _UIHostingView/safeAreaRegions") | ||
public var _disableSafeArea: Swift.Bool { | ||
get { | ||
host.explicitSafeAreaInsets == .zero | ||
} | ||
set { | ||
host.explicitSafeAreaInsets = newValue ? .zero : nil | ||
} | ||
} | ||
|
||
final public var _rendererConfiguration: _RendererConfiguration { | ||
get { host._rendererConfiguration } | ||
set { host._rendererConfiguration = newValue } | ||
} | ||
|
||
final public var _rendererObject: AnyObject? { | ||
host._rendererObject | ||
} | ||
|
||
func sizingOptionsDidChange(from oldSizingOptions: UIHostingControllerSizingOptions) { | ||
// TODO | ||
} | ||
} | ||
|
||
@available(macOS, unavailable) | ||
extension UIHostingController { | ||
public var safeAreaRegions: SafeAreaRegions { | ||
get { host.safeAreaRegions } | ||
set { host.safeAreaRegions = newValue } | ||
} | ||
} | ||
#endif |
42 changes: 42 additions & 0 deletions
42
...s/OpenSwiftUI/Integration/Hosting/UIKit/Controller/UIHostingControllerSizingOptions.swift
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// | ||
// UIHostingControllerSizingOptions.swift | ||
// OpenSwiftUI | ||
// | ||
// Audited for iOS 18.0 | ||
// Status: Complete | ||
|
||
#if os(iOS) | ||
|
||
/// Options for how a hosting controller tracks its content’s size. | ||
@available(macOS, unavailable) | ||
public struct UIHostingControllerSizingOptions: OptionSet, Sendable { | ||
public let rawValue: Int | ||
public init(rawValue: Int) { | ||
self.rawValue = rawValue | ||
} | ||
|
||
/// The hosting controller tracks its content's ideal size in its | ||
/// preferred content size. | ||
/// | ||
/// Use this option when using a hosting controller with a container view | ||
/// controller that requires up-to-date knowledge of the hosting | ||
/// controller's ideal size. | ||
/// | ||
/// - Note: This option comes with a performance cost because it | ||
/// asks for the ideal size of the content using the | ||
/// ``ProposedViewSize/unspecified`` size proposal. | ||
public static let preferredContentSize: UIHostingControllerSizingOptions = .init(rawValue: 1 << 0) | ||
|
||
/// The hosting controller's view automatically invalidate its intrinsic | ||
/// content size when its ideal size changes. | ||
/// | ||
/// Use this option when the hosting controller's view is being laid out | ||
/// with Auto Layout. | ||
/// | ||
/// - Note: This option comes with a performance cost because it | ||
/// asks for the ideal size of the content using the | ||
/// ``ProposedViewSize/unspecified`` size proposal. | ||
public static let intrinsicContentSize: UIHostingControllerSizingOptions = .init(rawValue: 1 << 1) | ||
} | ||
|
||
#endif |
76 changes: 0 additions & 76 deletions
76
Sources/OpenSwiftUI/Integration/Hosting/UIKit/UIHostingController.swift
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.