I know this thread is a little old, but I found something really interesting looking through SwiftUI’s interface file.
AnyView
provides a public initializer:
public struct AnyView: View {
// ...
public init?(_fromValue value: Any)
}
This means that SwiftUI can do something like the following in TupleView
:
extension TupleView {
/// Force-opens the given box.
internal func open(_ box: Any) -> AnyView {
guard let view = AnyView(_fromValue: box) else {
fatalError("TupleView contains non-view elements")
}
return view
}
internal var children: [AnyView] {
switch value {
case let tuple as? (Any, Any): return [open(tuple.0), open(tuple.1)]
// Larger-tuple dynamic casts...
default: return [open(value)]
}
}
}
Then, to access views' elements, the _VariadicView
APIs can be used. You, first, need to provide a root type conforming to a certain ...Root
protocol:
struct Root: _VariadicView.UnaryViewRoot {
func body(children: _VariadicView.Children) -> some View {
// Children is a random-access collection; here we just dump its child.
children.forEach { dump($0) }
return EmptyView()
}
}
The root type is used to layout elements that are passed to it by the _VariadicView.Tree
:
struct Container<Content: View>: View {
private let tree: _VariadicView.Tree<Root, Content>
init(@ViewBuilder _ content: () -> Content) {
tree = _VariadicView.Tree(Root(), content: content)
}
var body: some View { tree }
}
VStack
seems to be implemented this way. However, this approach is still quite limited by the lack of access to internal view-outputs APIs. As a result, you will only be able to use built-in containers and modifiers. Using these APIs also resulted in a lot of crashes in my test playground, so this is more of an educational post about the inner workings of SwiftUI.