💈Collapsible
可以收合或展開的 HStack。
Last updated
可以收合或展開的 HStack。
Last updated
我們在 2 號的矩形上放了 .onTapGesture(),所以點它就可收合或展開整個橫向堆疊 (HStack)。
/*
* Thinking in SwiftUI, Ch. 4, Exercises
*
* ⭐️ Required: 🌀View + .if
*/
import SwiftUI
import PlaygroundSupport
// 📦 Collapsible
struct Collapsible<Item, Content: View>: View {
// the HStack is expanded or not
@State private var expanded = false
// items to present in the HStack
var items: [Item]
// ⭐️ turn `Item` into `Content` view
var content: (Item) -> Content
// ⭐️ make i-th child view from items[i]
func child(at i: Int) -> some View {
// ⭐️ show child if expanded or last one
let isLastOne = i == self.items.endIndex - 1
let show = expanded || isLastOne
// ⭐️ if collapsed, shrink width to 10
let width: CGFloat? = show ? nil : 10
return content(items[i])
.frame(width: width)
.animation(.default)
.if(isLastOne){ // 🌀View + .if
$0.onTapGesture { self.expanded.toggle() }
}
} // child(at:)
// body of Collapsible
var body: some View {
let s: CGFloat = expanded ? 8 : 0 // spacing
return HStack(spacing: s) {
ForEach(items.indices) { self.child(at: $0) }
}
}
}
let colors: [Color] = [ .red, .orange, .purple ]
// 🖼 content view
struct ContentView: View {
var body: some View {
Collapsible(items: [0, 1, 2]) { i in // 📦 Collapsible
Rectangle()
.fill(colors[i])
.overlay(Rectangle().stroke(Color.black, lineWidth: 3))
.overlay(Text("\(i)"))
.frame(height: 100)
} //
.shadow(radius: 8)
.padding()
.background(Color.gray)
}
}
// 🏖 live view
PlaygroundPage.current.setLiveView(ContentView())