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

SwiftUI 如何缩小List顶部多余间距 避免行内容被裁剪

问题原因

调整Spacer高度不生效是SwiftUI List的默认机制导致的:

  • List底层封装自UITableView,未指定样式时默认使用InsetGrouped样式,会自动给内容区域顶部加固定内边距,和内部放置的内容无关
  • List默认给每一行保留最小行高、默认行边距,哪怕你给Spacer设置1pt高度,系统也会强制给行分配默认高度,自定义的frame参数优先级低于系统默认行配置
  • List默认开启内容裁剪,超出行布局边界的视图会被直接切掉,所以移除占位行后向上偏移的头像会显示不全。

修复方案

  1. 将List切换为.plain样式,清除默认分组内边距
  2. 清空所有行的默认listRowInsets,让自定义行高完全生效
  3. 用无固有尺寸的Color.clear做占位行,直接设置你需要的精确高度(比如设15pt就是原间距的一半)
  4. 适配不同iOS版本的系统默认边距,保证头像不会被裁剪

可直接运行的修改后代码

import SwiftUI
import PlaygroundSupport

struct CustomView: View {
    init() {
        // 适配iOS15及以下版本,清除List默认顶部偏移
        UITableView.appearance().contentInset.top = -20
    }
    var body: some View {
        NavigationView {
            List {
                // 顶部占位,高度直接自定义,这里设15pt即为原间距的一半
                Color.clear
                    .frame(height: 15)
                    .listRowBackground(Color.clear)
                    .listRowInsets(.init())
                
                UserLoginDetailsRowView()
                    .padding(.init(top: 0, leading: 5, bottom: 5, trailing: 5))
                    .listRowBackground(Color.clear)
                    .listRowInsets(.init())
                
                ForEach(1..<2) { _ in
                    VStack(alignment: .leading) {
                        Text("App Version")
                            .fixedSize(horizontal: false, vertical: true)
                            .font(.headline)
                            .foregroundColor(.white)
                        Text("1.1.0")
                            .fixedSize(horizontal: false, vertical: true)
                            .font(.subheadline)
                            .foregroundColor(.white)
                    }
                    .padding(.bottom, 15)
                    .listRowBackground(Color.clear)
                    .listRowInsets(.init())
                }
            }
            .listStyle(.plain)
            .navigationBarTitle("Back")
        }
    }
}

struct UserLoginDetailsRowView: View {
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: .center) {
                Spacer()
                Spacer()
                Text("User's full name").lineLimit(2).font(.headline)
                Text("Username").lineLimit(2).font(.subheadline)
                Spacer()
            }
            
            ZStack {
                Image(systemName: "person.circle")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 22 , height: 22)
                    .offset(x: geometry.size.width / 2.8, y: -geometry.size.height/4)
            }
        }.frame(minHeight: 60.0)
    }
}

PlaygroundPage.current.setLiveView(CustomView())

iOS16+ 更简便写法:不需要在init里修改UITableView全局配置,直接给List加以下修饰符即可精确控制顶部间距,不需要额外放置占位行:

.listStyle(.plain)
.contentMargins(.top, 15, for: .scrollContent)
.listRowSpacing(0)

直接修改contentMargins的top值就能任意调整顶部间距。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:15:29