简体   繁体   中英

Remove top padding from `List` in SwiftUI

I've seen similar questions like this one here on Stack Overflow, but none of them have been able to answer my question.

I have created a List , but I want to remove the padding space (marked with a red arrow) above the content in the List . How can I remove it when using a GroupedListStyle ?

截屏

This is a List within a VStack within a NavigationView that is displayed via fullscreenCover :

var body: some View {
  NavigationView {
    VStack {
      taskEventPicker
      myList
    }
    .navigationBarTitle("Add Task", displayMode: .inline)
  }
}

where taskEventPicker is a segmented Picker (boxed in green):

var taskEventPicker: some View {
  Picker("Mode", selection: $selection) { /* ... */ }
  .pickerStyle(SegmentedPickerStyle())
  .padding()
}

and myList is the form in question (boxed in yellow):

var myList: some View {
  List { /* ... */ }
  .listStyle(GroupedListStyle())
}

What I've Tried

Note: I'm looking for an answer that can apply to the GroupedListStyle . I understand that this issue does not occur with PlainListStyle . This padding issue also occurs with the default listStyle .

Thanks for the help!

Xcode version: 12.5

Firstly, I would say that GroupedListStyle is working as intended.

On iOS, the grouped list style displays a larger header and footer than the plain style, which visually distances the members of different sections.

You say you have tried this, but it does work for me (Xcode 12.5.1):

    List { ... }    
    .onAppear(perform: {
        UITableView.appearance().contentInset.top = -35
    })

You could also hide the list header, by using a ZStack with the List at the bottom of the stack and the Picker over the top. The Picker does have transparency, so you would also have to add an opaque view to act as background for the Picker .

var body: some View {
    NavigationView {
        ZStack(alignment: .top) {
            List { ... }
            .listStyle(.grouped)
            .padding(.top, 30)
            
            Color.white
                .frame(height: 65)
            
            Picker { ... }
            .pickerStyle(.segmented)
            .padding()
        }
        .navigationBarTitle("Add Task", displayMode: .inline)
    }
}

在此处输入图像描述

As far as I can see this just appears the same as PlainListStyle would do, but I assume you have a particular reason for wanting to use GroupedListStyle .

Give a header to the first section in your list: Section(header: Spacer(minLength: 0))

Disclaimer: this doesn't totally remove the top spacing, but it does yield the same result as the native Settings app.

Note: This worked for me on iOS 14.5

VStack {
    List {
        Section(header: Spacer(minLength: 0)) {
            Text(verbatim: "First Section")
        }

        Section {
            Text(verbatim: "Second Section")
        }
    }
    .listStyle(GroupedListStyle())
}

没有节标题 带节标题 原生设置应用

I had a similar setup where I had some views and a List in a VStack and I had an undesired space that appeared on the top of my List. In my case I needed to set the VStack spacing to 0 and that solved the issue because it was actually just spacing from the VStack.

VStack(spacing: 0) { ... }

my 2 cents. I arrived here for the same reason.

take a look at: https://developer.apple.com/forums/thread/662544

it' seems the correct approach.

The contentInsent part of the accepted answer works perfectly fine unless for instance as in my case, at the end of a navigation stack you want to use it in some detail view containing a List with navigationBarTitleDisplayMode set to .inline . When navigating back in the stack to a view using another List with navigationBarTitleDisplayMode set to .large , the List content and NavigationBar interlace awfully. And they probably might as well do whatever the navigationBarTitleDisplayMode is set to.

Switching to listStyle(.plain) in my case isn't a feasable option, because then in the detail view, I loose the beautifully animated built-in transitions to and from List's EditMode , that seem to exist only in the grouped listStyle varieties.

Finally, after quite a few days of frustration I figured out that tableHeaderView is the approach that works best for my problem - and of course, it works just as well to solve the original question. It's all in here ...:

XCode documentation

... and in this sentence:

"When assigning a view to this property [ie tableHeaderView ], set the height of that view to a nonzero value"

So I do like:

List {
  // bla bla bla
}
.listStyle(.grouped)
.onAppear {
  let tableHeaderView = UIView(frame: .zero)
  tableHeaderView.frame.size.height = 1
  UITableView.appearance().tableHeaderView = tableHeaderView
}

It's as simple as that. Hope it might help you, too!

extension View {
    /// Clear tableview and cell color
    func tableClearColor() {
        let tableHeaderView = UIView(frame: .zero)
        tableHeaderView.frame.size.height = 0.5
        UITableView.appearance().tableHeaderView = tableHeaderView
    }
}
List {
 ...
}
.headerTopPadding(padding: 0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM