SwiftUI(iOS 16):解决两个List之间的多余间距问题
问题描述
我用SwiftUI开发复杂应用时,做了个示例项目,发现Sheet/Panel里的两个独立List之间出现了大量多余间距,找不到原因。
涉及的两个List在PanelB里,分别是DateTimeView和ResultsDisplayList。PanelA是应用流程代码,不确定是否影响,想知道间距产生的原因。

示例代码
import SwiftUI import Foundation struct ContentView: View { @State var showPanel: Bool = false var body: some View { NavigationStack { VStack { Text("Hello World - Click Me").font(.largeTitle).foregroundColor(.blue) .onTapGesture { self.showPanel = true } }.sheet(isPresented: $showPanel) { ZStack { Color.secondary PanelA().padding(.top, 15.0) } } } } } struct PanelA: View { @State var showPanel: Bool = false var body: some View { NavigationStack { VStack { Button { showPanel = true } label: { Text("Click Me") } .buttonBorderShape(.roundedRectangle(radius: 15.0)) .padding() .background(Color.teal) } .presentationDetents([.medium, .large]) .presentationBackgroundInteraction(.enabled) .navigationDestination(isPresented: $showPanel) { PanelB() } } } } struct PanelB: View { var body: some View { ZStack { Color.purple.edgesIgnoringSafeArea(.all) VStack { DateTimeView().padding(.bottom, 20.0) ResultsDisplayList() Spacer() } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.purple) } } } struct DateTimeView: View { @State private var startDateTime = Date.now @State private var isAllDay = true var body: some View { List { Section("Event Date".uppercased()) { Toggle("all day", isOn: $isAllDay) DatePicker(selection: $startDateTime, in: startDateTime..., displayedComponents: [.date]) { Text("select date time").font(.body).foregroundColor(Color.black) } } } .listStyle(.insetGrouped) } } struct ResultsDisplayList: View { let results = ["Apple", "Orange", "Pineapple", "Cherries", "Strawberries", "Banana"] var body: some View { ScrollViewReader { _ in VStack(alignment: .leading, spacing: 8.0) { List { Section { ForEach(results, id: \.hashValue) { result in Text(result).font(.body) } } header: { Text("Results List") } } } } .onAppear { UITableView.appearance().backgroundColor = .clear UITableViewCell.appearance().backgroundColor = .clear } } }
问题原因及修复方法
两个List之间的多余间距主要来自两个点:
- 多余的嵌套容器:
ResultsDisplayList里把List包在了VStack中,这个VStack设置了spacing: 8.0,同时VStack本身会引入额外的布局空间,加上List默认的顶部内边距,叠加出了明显间距。 - List样式不统一:
DateTimeView用了.insetGrouped的listStyle,而ResultsDisplayList的List用了默认样式,不同样式的List自带的内边距、间距规则不一样,导致布局错位。
修复步骤:
- 移除
ResultsDisplayList里多余的VStack,直接在ScrollViewReader中返回List:
struct ResultsDisplayList: View { let results = ["Apple", "Orange", "Pineapple", "Cherries", "Strawberries", "Banana"] var body: some View { ScrollViewReader { _ in List { Section { ForEach(results, id: \.hashValue) { result in Text(result).font(.body) } } header: { Text("Results List") } } } .onAppear { UITableView.appearance().backgroundColor = .clear UITableViewCell.appearance().backgroundColor = .clear } } }
- 给
ResultsDisplayList的List添加.listStyle(.insetGrouped),和DateTimeView保持样式统一:
List { // 原有代码 } .listStyle(.insetGrouped)
- 按需调整
PanelB中DateTimeView的.padding(.bottom, 20.0),避免手动padding加剧间距问题。
内容的提问来源于stack exchange,提问作者tech_human
相关产品推荐
相关产品推荐

