【问题标题】:Fill height in scrollView in swiftUIswiftUI中scrollView的填充高度
【发布时间】:2020-11-02 18:25:09
【问题描述】:

我正在使用 swiftUI 进行编码,我有一个垂直的 scrollView(见屏幕截图),在其中 scrollView 我有另一个水平的 scrollView,在它下面我有一个 VStack 我想要高度将屏幕的其余部分填充到垂直scrollView 的底部,但我似乎无法让它工作。

垂直scrollView中的内容在某些情况下可能大于实际剩余空间,这就是我需要滚动视图的原因,但在某些其他情况下,内容小于剩余空间

这是我的代码:

    VStack {
        HeaderView
        
        ScrollView(.vertical, showsIndicators: false) {
            FriendsHorizontalScrollView()
            
            VStack {
                // I want this view to take all the remaining height left in the scrollView
                FullHeightView()
            }
            .frame(width: UIScreen.main.bounds.width)
        }
    }

我最终得到的是这样的:

我想要什么:

我尝试了几种解决方案,例如使用geometryReader 或将.frame(maxHeight: .infinity) 放在VStack 上,但似乎都无法正常工作。

【问题讨论】:

  • 那为什么还需要垂直滚动视图呢?
  • 我编辑了帖子,在某些情况下内容可能会更大,这就是我需要滚动视图的原因

标签: ios swift swiftui scrollview swift5


【解决方案1】:

这是基于视图偏好的可能方法的演示(ViewHeightKey 取自我的this 解决方案。使用 Xcode 12 / iOS 14 测试。

struct DemoLayoutInScrollView: View {
    @State private var height1: CGFloat = .zero
    @State private var height2: CGFloat = .zero
    var body: some View {
        VStack(spacing: 0) {
            HeaderView()

            GeometryReader { gp in
                ScrollView(.vertical, showsIndicators: false) {
                    VStack(spacing: 0) {
                        FriendsHorizontalScrollView()
                            .background(GeometryReader {
                                Color.clear
                                    .preference(key: ViewHeightKey.self, value: $0.frame(in: .local).size.height)
                            })
                            .onPreferenceChange(ViewHeightKey.self) { self.height1 = $0 }
                        VStack(spacing: 0) {
                            // I want this view to take all the remaining height left in the scrollView
                            FullHeightView()
                                .background(GeometryReader {
                                    Color.clear
                                        .preference(key: ViewHeightKey.self, value: $0.frame(in: .local).size.height)
                                })
                        }.frame(height: max(gp.size.height - self.height1, self.height2))
                        .background(Color.yellow)
                    }
                }
                .onPreferenceChange(ViewHeightKey.self) { self.height2 = $0 }
            }
        }.frame(maxWidth: .infinity)
    }
}

复制的帮助视图(用于测试)

struct FriendsHorizontalScrollView: View {
    var body: some View {
        Text("Horizontal Scroller")
            .frame(maxWidth: .infinity)
            .frame(height: 100)
            .background(Color.green)
    }
}

struct FullHeightView: View {
    var body: some View {
        ZStack {
            Color.red
            Text("Dynamic Content")
        }
        .frame(maxWidth: .infinity)
        .frame(height: 300)
    }
}

struct HeaderView: View {
    var body: some View {
        Rectangle().foregroundColor(.blue)
            .frame(height: 60)
            .overlay(Text("Header"))
    }
}

【讨论】:

    【解决方案2】:

    这可以通过使用GeometryReader 来实现。这个想法是设置你的根视图的minHeight

    import SwiftUI
    
    struct ContentView: View {
        var body: some View {
            GeometryReader { proxy in
                ScrollView {
                    VStack(spacing: 0) {
                        Text("View 1")
                            .frame(height: 100)
                            .frame(maxWidth: .infinity)
                            .background(Color.green)
                        Text("View 2")
                            .frame(height: 100)
                            .frame(maxWidth: .infinity)
                            .background(Color.gray)
                        VStack {
                            Text("VStack")
                            Text("View 3")
                                .frame(height: 100)
                                .frame(maxWidth: .infinity)
                                .background(Color.blue)
                                .padding()
                        }
                        .frame(maxHeight: .infinity)
                        .background(Color.yellow)
                    }
                    .frame(minHeight: proxy.size.height)
                }
            }
            .edgesIgnoringSafeArea(.all)
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    

    【讨论】:

    • 优秀的答案,比我认为接受的更好,因为它不涉及额外的变量和重绘。
    猜你喜欢
    • 2020-03-13
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    相关资源
    最近更新 更多