Skip to content

Commit

Permalink
Merge pull request #187 from OpenSwiftUIProject/feature/hosting
Browse files Browse the repository at this point in the history
Update UIHosting implementation to fix HostingExample example
  • Loading branch information
Kyle-Ye authored Feb 2, 2025
2 parents 866bb21 + 9472ae3 commit 4393a39
Show file tree
Hide file tree
Showing 42 changed files with 1,616 additions and 570 deletions.
6 changes: 3 additions & 3 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"originHash" : "1cf308da26a892a1962d7acfd0aeae3c95ac506674d47f80a07474eb8476d770",
"originHash" : "4c9f2a8a5476609cccba7d42115419684b57b545e53f9107779b8bbe1569a5fe",
"pins" : [
{
"identity" : "darwinprivateframeworks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/OpenSwiftUIProject/DarwinPrivateFrameworks.git",
"state" : {
"branch" : "main",
"revision" : "5a0e8d14d6fbe728951ece9ded2c6f2a6708f5a6"
"revision" : "be1c53ecb3b0fbeedcddf26ece937ab3c774c03d"
}
},
{
Expand All @@ -25,7 +25,7 @@
"location" : "https://github.com/OpenSwiftUIProject/OpenGraph",
"state" : {
"branch" : "main",
"revision" : "4aeda45233cb3d8623d819e98aeca4b86a8a3a7d"
"revision" : "a161f230e09b0dbe6db74618b30c137707960fc8"
}
},
{
Expand Down
24 changes: 24 additions & 0 deletions Sources/OpenSwiftUI/CoreGlue/OpenSwiftUIGlue.swift
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
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 {}
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)]"
}
}

This file was deleted.

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
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

This file was deleted.

Loading

0 comments on commit 4393a39

Please sign in to comment.