Remove empty space between section in SwiftUI
Asked Answered
D

3

5

does anyone know of a way to remove the space between sections of a list in Swiftui? I tried inserting the footer as an EmptyView but it doesn't work. This problem occurs from iOS 16 onwards because on 15 it was enough to insert this line in the init: UITableView.appearance().sectionFooterHeight = 0

List {
     ForEach(servicesEnv.dictionary.keys.sorted(), id:\.self) { key in
            Section(header: SectionHeader(sectionName: "\(key)"),
                    footer: EmptyView()) {
                         MyView()
                            }
                        }
                    }
                }
            }
            .listStyle(GroupedListStyle())
Doublestop answered 17/1, 2023 at 8:49 Comment(3)
try adding .listRowInsets(EdgeInsets())Damnation
Please add some sample code that demonstrates the problem, that can be run by someone trying to solve it. In SwiftUI, ideally a struct ContentView that can be pated into Xcode. Please read minimal reproducible example.Cartridge
Does this answer your question? SwiftUI: How to remove spacing between 2 sections? (iOS16)Foist
V
5

Starting Xcode 15, iOS 17 / watchOS 10 (Still in Beta as of 03.08.2023) there are new view modifiers that allow you to set the spacing between sections to either a fixed value or variable ListSectionSpacing

// Sets a fixed CGFloat value

.listSectionSpacing(2)

https://developer.apple.com/documentation/swiftui/view/listsectionspacing(_:)-a2sn

// Sets a flexible ListSectionSpacing

.listSectionSpacing(.compact)

https://developer.apple.com/documentation/swiftui/view/listsectionspacing(_:)-5t518

Victoria answered 3/8, 2023 at 13:44 Comment(0)
B
3

I have found a solution that should work for every iOS version. (I have tested it myself on iOS 15, 16, and 17.)

It is possible to completely remove the spacing between sections. The solution is to set .environment(\.defaultMinListHeaderHeight, 0), .listRowInsets(EdgeInsets()) and explicitly define the contents' frame height for both the header and footer. Please note that it won't work if you use EmptyViews there.

Form {
    Section {
        Text("Item 1")
    } header: {
        Rectangle().frame(height: 0)
    } footer: {
        Rectangle().frame(height: 0)
    }
    .listRowInsets(EdgeInsets())

    Section {
        Text("Item 2")
    } header: {
        Rectangle().frame(height: 0)
    } footer: {
        Rectangle().frame(height: 0)
    }
    .listRowInsets(EdgeInsets())
}
.environment(\.defaultMinListHeaderHeight, 0)
// iOS 15 (should also work on iOS 13 & 14)
.introspect(.list, on: .iOS(.v15)) { tableView in
    tableView.sectionHeaderHeight = 0
    tableView.sectionFooterHeight = 0
}
Bunns answered 13/2, 2024 at 16:9 Comment(0)
O
-2

iOS 13-15 List is UITableView (add code below in init):

UITableView.appearance().sectionFooterHeight = 0

iOS 16-17 List is UICollectionView (add code below in init):

var layoutConfig = UICollectionLayoutListConfiguration(appearance: .grouped)
layoutConfig.headerMode = .supplementary
layoutConfig.headerTopPadding = 0
layoutConfig.footerMode = .supplementary
let listLayout = UICollectionViewCompositionalLayout.list(using: layoutConfig)
UICollectionView.appearance().collectionViewLayout = listLayout

iOS 17: The previous solution still works, but there is a new method:

.listSectionSpacing(0)

Changes you apply to UITableView.appearance() and UICollectionView.appearance() will also have an effect on all others Lists in your app. But you can apply changes only for current List using swiftui-introspect with code above replacing UITableView.appearance() and UICollectionView.appearance() by tableView and collectionView

.introspectTableView { tableView in
    // code below
}

.introspectCollectionView { collectionView in
    // code below
}
Oui answered 16/10, 2023 at 5:31 Comment(1)
it is crashing on ios 16.Epanaphora

© 2022 - 2025 — McMap. All rights reserved.