SwiftUI is perfectly happy working with optional views, such as Image? and Text?.
👉 SwiftUI: Handling optionals - Erica Sadun
let value: Int? = 1
let view = value // Int?
.map { Text("\($0)") } // Text?
import SwiftUI
// 📦 MyView<LeftContent, RightContent>
struct MyView<LeftContent: View, RightContent: View>: View {
let leftContent : LeftContent
let rightContent: RightContent? // ⭐️ Optional<RightContent>
// ⭐️ MyView(makeLeftContent: {}, makeRightContent: {})
init(
@ViewBuilder makeLeftContent : () -> LeftContent,
@ViewBuilder makeRightContent: () -> RightContent?
) {
self.leftContent = makeLeftContent()
self.rightContent = makeRightContent()
}
var body: some View { // MyView.Body
HStack { // HStack<TupleView<(L, R)>>
self.leftContent // L: LeftContent
self.rightContent // R: Optional<RightContent>
}
}
}
// 🌀 helper extension
extension MyView where RightContent == EmptyView {
// ⭐️ MyView(makeLeftContent: {})
// ⭐️ MyView {}
init(@ViewBuilder makeLeftContent: () -> LeftContent) {
self.init(
makeLeftContent : makeLeftContent,
// ⭐️ 這裡的 `nil` 是指 `Optional<EmptyView>.none`
makeRightContent: { nil }
)
}
}
// init in extension
let v1 = MyView { Text("Hello") }
// init in definition
let v2 = MyView(makeLeftContent: {
Text("Hello")
}, makeRightContent: {
Text("World")
})
// inspect their types
let T1 = type(of: v1)
let T2 = type(of: v2)
print(T1) // MyView<Text, EmptyView>
print(T2) // MyView<Text, Text>
print(T1.Body.self) // HStack<TupleView<(Text, Optional<EmptyView>)>>
print(T2.Body.self) // HStack<TupleView<(Text, Optional<Text>)>>