1

before updating to iOS 26 my list was looking fine but now it has abnormal paddings and because I am using fixed height, I had to increase the height from 40 to 60 to fit the text. There are currently two issues I am facing.

  1. The list is now not being clipped at the bottom edges when I increase the height to 60
  2. When the text is more than one line, unlike before it does not decrease padding to fit it in the specified height but instead cuts it off.

Following are my modifiers for my view, I have also treid with minHeight and mxHeight but both issues persist

struct SwiftUIView: View {
    var body: some View {
        let names = [Name(name: "Name 1"), Name(name: "Name 2 Name Double line list row text which should fit in it too")]
        
        ZStack {
            Color(.pink)
            List {
                Section {
                    ForEach(names) { name in
                        Button {
                            // do action
                        } label: {
                            Text(name.name)
                        }
                        
                    }
                    
                }
            }
            .listStyle(.plain)
            .clipShape(.rect(cornerRadius: 15))
            .scrollContentBackground(.hidden)
            .layoutPriority(1)
            .frame(height: 2 * 52)
            .padding(10)
            
        }
    }
}

Desired behaviour is that like before iOS 26 the padding would decrease for a row when the text is multiline.

6
  • 1
    Try applying the .clipShape after the .frame. Otherwise, please provide enough code to allow the problem to reproduced (in other words, more than a few modifiers). A screenshot would also be helpful to illustrate the issue. Commented Nov 26 at 14:47
  • I have adjusted the code and even now its the same problem Commented 2 days ago
  • This code is still not complete and does not demonstrate the problem when run in isolation. The context in which the list is being shown is probably important, otherwise the clip shape is not seen. But if you are trying to set the height of the list to the height of its contents then this post might help: How can I make a List auto-size to its content height (without manually setting frame height)? Commented 2 days ago
  • I adjusted the code and also looked at the question you shared, however I am also using the Section in swiftUI, but still my text is not being adjusted in the row, which was happening previously before I updated to iOS 26. Commented 2 days ago
  • Doy you think you can share your code that you tried? Commented 2 days ago

1 Answer 1

0

As discussed in the comments, the modifier .onScrollGeometryChange can be used to measure the height of the list precisely (requires iOS 18). You can then set this height on the list, before applying the clip shape. This approach also adapts to changes in the text size.

Here is the fully updated example to show it working:

struct SwiftUIView: View {
    let names = [
        Name(name: "Name 1"),
        Name(name: "Name 2 Name Double line list row text which should fit in it too")
    ]
    @State private var listHeight: CGFloat?

    var body: some View {
        ZStack {
            Color.pink
                .ignoresSafeArea()

            List {
                Section {
                    ForEach(names) { name in
                        Button {
                            // do action
                        } label: {
                            Text(name.name)
                        }
                    }
                }
            }
            .listStyle(.plain)
            .onScrollGeometryChange(for: CGFloat.self, of: \.contentSize.height) { _, height in
                if height > 0 {
                    listHeight = height
                }
            }
            .frame(height: listHeight)
            .clipShape(.rect(cornerRadius: 15))
            .scrollContentBackground(.hidden)
            .padding(10)
        }
    }
}

struct Name: Identifiable {
    let id = UUID()
    let name: String
}

Screenshot


Re. your point 2:

When the text is more than one line, unlike before it does not decrease padding to fit it in the specified height but instead cuts it off.

If you want the text to have less vertical padding when it wraps to 2 or more lines then try setting the top and bottom row insets to 0 using .listRowInsets:

ForEach(names) { name in
    Button {
        // do action
    } label: {
        Text(name.name)
    }
    .listRowInsets(.init(top: 0, leading: 16, bottom: 0, trailing: 16)) // 👈 here
}

Rows that fit on 1 line will still have some vertical padding by virtue of the environment value defaultMinListRowHeight. This is the case for the first line in your example:

Screenshot

Sign up to request clarification or add additional context in comments.

5 Comments

I noticed a buggy behaviour, onScrollGeometryChange, sometimes the list doesn't show up until I try to scroll the view, and then it shows up with the correct height. I understand it's maybe because this modifier triggers on scrolling? Am I right
I haven't seen that happen. Did you include the check if height > 0 as shown in the code above? And is the type of the state variable an optional, also as shown?
Yes, infact I copy pasted it to make sure I did not make any typing error. This isn't happening every time,only sometimes, so its not easy to reproduce. One question I have is, should nt this solution also work? Theoretically I thought should have worked but does not. .background { GeometryReader { proxy in Color.clear .onAppear { self.listHeight = proxy.size.height } } }
The height measured by a GeometryReader in the background will be the full (greedy) height of the list, not the height of its contents, so probably not useful. The issue with initial size may be because other content on the same page is competing for the same screen space. This gets back to my original request for an MRE that showed the context of how the list was being shown. If the circumstances are more complex, I would suggest raising a new question. This should include a complete MRE that incorporates the solution you have from here.
Ps. You could try changing the if check to a larger value, for example, 10. Or try an additional frame modifier: .frame(minHeight: 10). Then if 10 doesn't help, try the approximate height of one row (40?).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.