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

SwiftUI(iOS 16):解决两个List之间的多余间距问题

问题描述

我用SwiftUI开发复杂应用时,做了个示例项目,发现Sheet/Panel里的两个独立List之间出现了大量多余间距,找不到原因。

涉及的两个List在PanelB里,分别是DateTimeView和ResultsDisplayList。PanelA是应用流程代码,不确定是否影响,想知道间距产生的原因。

两个List间的多余间距

示例代码
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之间的多余间距主要来自两个点:

  1. 多余的嵌套容器:ResultsDisplayList里把List包在了VStack中,这个VStack设置了spacing: 8.0,同时VStack本身会引入额外的布局空间,加上List默认的顶部内边距,叠加出了明显间距。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:20:01