首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使GeometryReader适合抽屉内容

使GeometryReader适合抽屉内容
EN

Stack Overflow用户
提问于 2021-04-29 02:18:21
回答 1查看 40关注 0票数 0

如何使GeometryReader适合中间的ExpandingDrawer内容?

(复制和粘贴-可用):

代码语言:javascript
复制
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()的各种组合,但我还在苦苦挣扎...

EN

回答 1

Stack Overflow用户

发布于 2021-04-29 04:24:29

为了避免GeometryReader改变我们的视图,我们可以把它放在一个.overlay()中。

示例:

代码语言:javascript
复制
struct ContentView: View {
    class Storage {
        var geo: GeometryProxy! {
            didSet {
                print(geo.size)
            }
        }
    }
    
    let storage = Storage()
    
    /* ... */
}
代码语言:javascript
复制
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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67305800

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档