Skip to content

Commit d8ce4f4

Browse files
committed
Update Layout
1 parent 039b8b5 commit d8ce4f4

File tree

2 files changed

+150
-37
lines changed

2 files changed

+150
-37
lines changed

Sources/OpenSwiftUICore/Layout/Layout.swift

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,156 @@ public struct _LayoutTrait<K>: _ViewTraitKey where K: LayoutValueKey {
15491549
@available(*, unavailable)
15501550
extension _LayoutTrait: Sendable {}
15511551

1552+
// MARK: - Layout + View
1553+
1554+
extension Layout {
1555+
/// Combines the specified views into a single composite view using
1556+
/// the layout algorithms of the custom layout container.
1557+
///
1558+
/// Don't call this method directly. SwiftUI calls it when you
1559+
/// instantiate a custom layout that conforms to the ``Layout``
1560+
/// protocol:
1561+
///
1562+
/// BasicVStack { // Implicitly calls callAsFunction.
1563+
/// Text("A View")
1564+
/// Text("Another View")
1565+
/// }
1566+
///
1567+
/// For information about how Swift uses the `callAsFunction()` method to
1568+
/// simplify call site syntax, see
1569+
/// [Methods with Special Names](https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID622)
1570+
/// in *The Swift Programming Language*.
1571+
///
1572+
/// - Parameter content: A ``ViewBuilder`` that contains the views to
1573+
/// lay out.
1574+
///
1575+
/// - Returns: A composite view that combines all the input views.
1576+
@_alwaysEmitIntoClient
1577+
@_disfavoredOverload
1578+
public func callAsFunction<V>(@ViewBuilder _ content: () -> V) -> some View where V: View {
1579+
return _VariadicView.Tree(_LayoutRoot(self)) { content() }
1580+
}
1581+
1582+
@_spi(_)
1583+
@available(*, deprecated, message: "replaced by implicit function call")
1584+
@_alwaysEmitIntoClient
1585+
public func content<V>(@ViewBuilder _ content: () -> V) -> some View where V: View {
1586+
return callAsFunction(content)
1587+
}
1588+
}
1589+
1590+
// MARK: - LayoutRoot
1591+
1592+
@frozen
1593+
public struct _LayoutRoot<L>: _VariadicView.UnaryViewRoot where L: Layout {
1594+
@usableFromInline
1595+
var layout: L
1596+
1597+
@inlinable package init(_ layout: L) { self.layout = layout }
1598+
1599+
nonisolated public static func _makeView(
1600+
root: _GraphValue<_LayoutRoot<L>>,
1601+
inputs: _ViewInputs,
1602+
body: (_Graph, _ViewInputs) -> _ViewListOutputs
1603+
) -> _ViewOutputs {
1604+
L._makeLayoutView(
1605+
root: root[offset: { .of(&$0.layout) }],
1606+
inputs: inputs,
1607+
body: body
1608+
)
1609+
}
1610+
}
1611+
1612+
@available(*, unavailable)
1613+
extension _LayoutRoot: Sendable {}
1614+
1615+
// MARK: - AnyLayoutProperties
1616+
1617+
package struct AnyLayoutProperties: Rule, AsyncAttribute {
1618+
@Attribute var layout: AnyLayout
1619+
1620+
package var value: Axis? {
1621+
layout.storage.layoutProperties.stackOrientation
1622+
}
1623+
1624+
package init(layout: Attribute<AnyLayout>) {
1625+
_layout = layout
1626+
}
1627+
}
1628+
1629+
// MARK: - ViewSizeCache
1630+
1631+
/// A cache for storing and retrieving view sizes based on proposed size values.
1632+
///
1633+
/// `ViewSizeCache` provides an efficient way to cache calculated sizes for views,
1634+
/// avoiding redundant size calculations when the same proposed size is requested multiple times.
1635+
package struct ViewSizeCache {
1636+
private var cache: Cache3<ProposedViewSize, CGSize>
1637+
1638+
/// Creates a new view size cache.
1639+
///
1640+
/// - Parameter cache: An optional pre-configured cache. If not provided, a new cache will be created.
1641+
package init(cache: Cache3<ProposedViewSize, CGSize> = .init()) {
1642+
self.cache = cache
1643+
}
1644+
1645+
/// Retrieves a cached size for the given proposed size, computing it if not already cached.
1646+
///
1647+
/// This method returns a cached value if available. If the value isn't cached,
1648+
/// it calls the provided closure to compute the value, caches it, and then returns it.
1649+
///
1650+
/// - Parameters:
1651+
/// - k: The proposed size to use as a key for the cache lookup.
1652+
/// - makeValue: A closure that computes the size when no cached value is available.
1653+
/// - Returns: The cached or newly computed size.
1654+
@inline(__always)
1655+
package mutating func get(_ k: _ProposedSize, makeValue: () -> CGSize) -> CGSize {
1656+
cache.get(ProposedViewSize(k), makeValue: makeValue)
1657+
}
1658+
}
1659+
1660+
// MARK: - _GraphInputs / _ViewInputs + needsDynamicLayout
1661+
1662+
extension _GraphInputs {
1663+
package var needsDynamicLayout: Bool {
1664+
get { options.contains(.needsDynamicLayout) }
1665+
set { options.setValue(newValue, for: .needsDynamicLayout) }
1666+
}
1667+
}
1668+
1669+
extension _ViewInputs {
1670+
package var needsDynamicLayout: Bool {
1671+
get { base.needsDynamicLayout }
1672+
set { base.needsDynamicLayout = newValue }
1673+
}
1674+
}
1675+
1676+
// MARK: - Deprecated types for @spi(_)
1677+
1678+
@_spi(_)
1679+
@available(*, deprecated, renamed: "Layout")
1680+
public typealias ViewLayout = Layout
1681+
1682+
@_spi(_)
1683+
@available(*, deprecated, renamed: "LayoutSubview")
1684+
public typealias ViewLayoutSubview = LayoutSubview
1685+
1686+
@_spi(_)
1687+
@available(*, deprecated, renamed: "LayoutSubviews")
1688+
public typealias ViewLayoutSubviews = LayoutSubviews
1689+
1690+
@_spi(_)
1691+
@available(*, deprecated, renamed: "LayoutProperties")
1692+
public typealias ViewLayoutProperties = LayoutProperties
1693+
1694+
@_spi(_)
1695+
@available(*, deprecated, renamed: "LayoutValueKey")
1696+
public typealias ViewLayoutKey = LayoutValueKey
1697+
1698+
@_spi(_)
1699+
@available(*, deprecated, renamed: "_LayoutRoot")
1700+
public typealias _ViewLayoutRoot<L> = _LayoutRoot<L> where L : Layout
1701+
15521702
// MARK: - threadLayoutData
15531703

15541704
@_transparent

Sources/OpenSwiftUICore/Layout/View/ViewSizeCache.swift

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)