首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用SwiftUI平面表删除iOS16中的节头顶部填充

如何用SwiftUI平面表删除iOS16中的节头顶部填充
EN

Stack Overflow用户
提问于 2022-09-03 13:36:34
回答 3查看 990关注 0票数 9

当我们使用SwiftUI列表组件并需要一个节标题时,顶部填充将出现在每个节的标题上。

在iOS15下,我们使用UITableView.appearance().sectionHeaderTopPadding = 0来解决这个问题。查看附件iOS15 15&Xcode14 14构建截图。

但在iOS16中,这种设置似乎不起作用。查看附件iOS16 16&Xcode14 14构建屏幕截图,当滚动:iOS16 16&Xcode14 14编译卷轴

因此,我的问题是如何删除iOS16中的节标题顶部填充,当滚动列表时,它的节标题将被固定,就像附件iOS15 15&Xcode14 14编译卷轴一样。

由于iOS16,SwiftUI List组件似乎使用UICollectionView而不是UITableView,所以我尝试通过全局设置UICollectionView的顶部填充来解决这个问题。不幸的是,我没有找到一种方法来设置UICollectionView的部分顶部填充。

我的密码在下面。

代码语言:javascript
复制
//
//  ContentView.swift
//  ListIniOS16
//
//  Created by Eric on 2022/07/23.
//

import SwiftUI

struct ContentView: View {
    @State private var collections: [ListData] = ListData.collection

    init() {
        let appBarTheme = UINavigationBarAppearance()
        appBarTheme.configureWithOpaqueBackground()
        appBarTheme.backgroundColor = UIColor(.gray)
        UINavigationBar.appearance().standardAppearance = appBarTheme
        UINavigationBar.appearance().scrollEdgeAppearance = appBarTheme
        if #available(iOS 15.0, *) {
            // can fix sectionHeaderTopPadding issue in iOS15,
            // but in iOS16 it doesn't work.
            UITableView.appearance().sectionHeaderTopPadding = 0
        }
    }
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(collections) { item in
                        Section(header: SectionHeader(title: item.group)) {
                            ForEach(item.rows) { row in
                                Text(row.name)
                            }
                        }
                        .listRowBackground(Color.gray.opacity(0.3))
                    }
                }
                .listStyle(.plain)
            }
            .navigationTitle("ListSectionHeader")
            .navigationBarTitleDisplayMode(.inline)
        }
    }

    struct SectionHeader: View {
        let title: String

        var body: some View {
            ZStack(alignment: .leading) {
                Color(.lightGray)
                    .frame(maxWidth: .infinity)

                Text(title)
                    .font(.system(size: 16, weight: .bold))
                    .foregroundColor(.primary)
                    .padding(EdgeInsets(top: 10, leading: 18, bottom: 10, trailing: 18))
            }
            .listRowInsets(EdgeInsets())
        }
    }
}

struct ListData: Codable, Identifiable {
    var id = UUID()
    let group: String
    let rows: [Row]
}

extension ListData {
    static let collection: [ListData] = [.a, .b, .c]

    static let a = ListData(group: "A", rows: [.row1, .row2, .row3])

    static let b = ListData(group: "B", rows: [.row1, .row2, .row3, .row1, .row2, .row3])

    static let c = ListData(group: "C", rows: [.row1, .row2, .row3, .row1, .row2, .row3, .row1, .row2, .row3])
}

struct Row: Codable, Equatable, Identifiable {
    var id = UUID()
    let name: String
}

extension Row {
    static let row1 = Row(name: "Row1")
    static let row2 = Row(name: "Row2")
    static let row3 = Row(name: "Row3")
}

非常感谢。

EN

回答 3

Stack Overflow用户

发布于 2022-09-13 12:59:33

您可以从UICollectionViews中的节标题中删除顶部填充,如下所示:

代码语言:javascript
复制
var layoutConfig = UICollectionLayoutListConfiguration(appearance: .plain)
layoutConfig.headerMode = .supplementary
layoutConfig.headerTopPadding = 0
let listLayout = UICollectionViewCompositionalLayout.list(using: layoutConfig)
UICollectionView.appearance().collectionViewLayout = listLayout

编辑:不幸的是,我刚刚看到它覆盖了某些SwiftUI修饰符,比如.listRowSeparator().onDelete()

票数 2
EN

Stack Overflow用户

发布于 2022-10-07 19:26:58

我有和你一样的困境。一开始,我考虑使用我的标题作为另一个单元格,虽然我确实消除了.environment(\.defaultMinListRowHeight, 0)的所有间距,但我当然没有为滚动而固定页眉。最终,我在一个LazyVStack中替换了我的列表,并调整了我的内容,使其看起来像以前的样子(有间距、列表分隔符等等)。

代码语言:javascript
复制
ScrollView {
  LazyVStack(alignment: .leading, pinnedViews: [.sectionHeaders]) {
    Content()
  }
}
票数 0
EN

Stack Overflow用户

发布于 2022-10-26 09:43:50

您可以使用GeometryReader来找出标题的高度,而不是使用负填充,将列表向上移动。就像这样:

代码语言:javascript
复制
struct RootView: View {

@State var headerHeight = 0.0

var body: some View {
    List {
        Section {
            Text("11111")
            Text("22222")
            Text("22222")
            Text("22222")
            Text("22222")
            Text("22222")
            Text("22222")
            Text("22222")
        } header: {
            header
        }
        .listRowInsets(EdgeInsets())
    }
    .listStyle(GroupedListStyle())
    .padding(.top, -headerHeight)
}

private var header: some View {
    Color
        .clear
        .background(GeometryReader { geometryReader -> Color in
            DispatchQueue.main.async {
                print("\(geometryReader.frame(in: .local).height)")
                if headerHeight != geometryReader.frame(in: .local).height {
                    headerHeight = geometryReader.frame(in: .local).height
                }
            }
            return .clear
        })
}}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73592661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档