如何将GeometryReader
放入中间的ExpandingDrawer
内容?
(可复制和粘贴(:
import SwiftUI
struct ExpandingDrawerButton: View {
@Binding var isExpanded: Bool
var body: some View {
Button(action: { withAnimation { isExpanded.toggle() } }) {
Text(isExpanded ? "Close" : "Open")
}
}
}
struct ExpandingDrawer<Content: View>: View {
@Binding var isExpanded: Bool
var content: () -> Content
var body: some View {
content()
.frame(minWidth: 0, maxWidth: .infinity, minHeight: nil, maxHeight: contentHeight)
.allowsHitTesting(isExpanded)
.clipped()
.transition(.slide)
}
private var contentHeight: CGFloat? {
isExpanded ? nil : CGFloat(0)
}
}
struct DrawerTestView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
struct ContentView: View {
@State var isExpanded = false
var body: some View {
GeometryReader { geo in
VStack(spacing: 0) {
top
.frame(height: geo.size.height * 1/4)
middle
bottom
.frame(height: geo.size.width)
}
}
}
var top: some View {
ZStack(alignment: Alignment(horizontal: .center, vertical: .bottom)) {
Rectangle()
.foregroundColor(.blue.opacity(0.2))
ExpandingDrawerButton(isExpanded: $isExpanded)
.padding()
}
}
var middle: some View {
ExpandingDrawer(isExpanded: $isExpanded) {
middleContent
}
}
var middleContent: some View {
GeometryReader { geo in
VStack {
ForEach(0..<10) { _ in
Button(action: {}) { Text("Random shit") }
}
Text("Don't know how tall...")
Text("Height can change...")
Text("But does need to fit snug (no extra space)")
}
}
}
var bottom: some View {
ZStack {
Rectangle()
.foregroundColor(.red)
.aspectRatio(1, contentMode: .fit)
VStack {
Text("Needs to be a square...")
Text("Okay if pushed below edge of screen...")
}
}
}
}
}
我试过.fixedSize()
和.aspectRatio()
的各种组合,但我很挣扎。。。
为了避免GeometryReader
更改我们的视图,我们可以将其放在.overlay()
中。
示例:
struct ContentView: View {
class Storage {
var geo: GeometryProxy! {
didSet {
print(geo.size)
}
}
}
let storage = Storage()
/* ... */
}
var middleContent: some View {
VStack {
ForEach(0..<10) { _ in
Button(action: {}) { Text("Random stuff") }
}
Text("Don't know how tall...")
Text("Height can change...")
Text("But does need to fit snug (no extra space)")
}
.overlay(
GeometryReader { geo in
Rectangle()
.fill(Color.clear)
let _ = storage.geo = geo
}
)
}
现在可以使用storage.geo
访问此视图的GeometryProxy
。