You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI:如何让PlaceholderView占满ScrollView头部外的剩余空间?

SwiftUI中让PlaceholderView在头部下方剩余空间居中的实现方案

核心思路

通过捕获顶部HStack的实际高度,计算屏幕总高度与头部高度的差值,将该差值设为PlaceholderView的高度,同时确保PlaceholderView内部内容在该高度范围内垂直居中。

具体实现步骤

  1. 定义PreferenceKey捕获视图高度
    创建自定义PreferenceKey,用于传递HStack的高度值:
struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = nextValue()
    }
}
  1. 捕获HStack的实际高度并计算剩余空间
    在头部HStack上添加背景视图,通过GeometryReader读取其高度,再用屏幕总高度减去该值得到PlaceholderView的目标高度:
@State private var headerHeight: CGFloat = 0

var body: some View {
    GeometryReader { geometry in
        ScrollView {
            HStack(spacing: .zero) {
                Text("This is my greeting to you")
                Spacer()
            }
            .background(
                GeometryReader { proxy in
                    Color.clear
                        .preference(key: ViewHeightKey.self, value: proxy.size.height)
                }
            )
            .onPreferenceChange(ViewHeightKey.self) { newHeight in
                headerHeight = newHeight
            }
            
            if greetings.isEmpty {
                PlaceholderView()
                    .frame(height: geometry.size.height - headerHeight)
                    .frame(maxWidth: .infinity)
            } else {
                LazyVStack {
                    ForEach(greetings, id: \.self) { greeting in
                        Text(greeting)
                    }
                }
            }
        }
    }
}
  1. 调整PlaceholderView内部布局
    修改PlaceholderView,让其内部内容在分配的高度范围内垂直居中:
struct PlaceholderView: View {
    var body: some View {
        VStack {
            Image(systemName: "hand.wave")
            Text("Hello world!")
        }
        .frame(maxHeight: .infinity)
    }
}

原理说明

  • PreferenceKey用于在视图层级间传递HStack的实际渲染高度,避免硬编码或估算高度带来的误差。
  • 用屏幕总高度减去头部高度得到的剩余空间,刚好是HStack下方的可用区域,将其设为PlaceholderView的高度,确保占位视图不会超出或不足该区域。
  • 给PlaceholderView内部的VStack设置maxHeight: .infinity,让其在父视图高度范围内自动实现垂直居中。

内容的提问来源于stack exchange,提问作者lazarevzubov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:42:18