'How to align swiftUI List perfectly?

I have a simple view, a rectangle and a list of numbers, what I want is both of this have the same 20 horizontal padding, it is simple for rectangle but I don't know how to set a proper value for list. I use PlainListStyle() but in the iPhone SE and Pro Max have different horizontal padding that makes UI to be different from iPhone to iPhone that shouldn't be.

enter image description here enter image description here

things I tried :

  1. Different list style with different padding and setting different width value. 2.Set EdgeInsets for rows in list to find the perfect value.

.listRowInsets(EdgeInsets(top: 0, leading: 6, bottom: 20, trailing: 11))

but non of them worked. Do you know how can I align list and rectangle by 20 padding?

What am I missing?

VStack(spacing: 0) {
            
            Rectangle()
                .foregroundColor(.red)
                .frame(maxWidth : .infinity)
                .frame( height: 100)
                .padding(.horizontal,20)
            
            List {
                ForEach((1...20).reversed(), id: \.self) { number in
                    
                        Text("\(number)")
                      
                }
            }
            .listStyle(PlainListStyle())
            //          .listStyle(SidebarListStyle())
            //            .listStyle(InsetGroupedListStyle())
            //            .listStyle(InsetListStyle())
            //           .listStyle(GroupedListStyle())
          

            
            
        }


Solution 1:[1]

This approach can be a possible way for solving your issue:

struct ContentView: View {
    
    @State private var size: CGFloat? = nil
    @State private var backgroundSize: CGFloat? = nil
    @State private var paddingValue: CGFloat = .zero
    
    var body: some View {
        
        VStack(spacing: 0) {
            
            Rectangle()
                .foregroundColor(.red)
                .frame(maxWidth : .infinity)
                .frame(height: 100)
                .padding(.horizontal, paddingValue)
            
            
            List {
                
                if (size == nil) {
                    
                    GeometryReader { proxy in
                        
                        Color.clear
                            .onAppear(perform: { size = proxy.size.width })
                        
                    }
                    .frame(height: .zero)
                }
                
                ForEach((1...20).reversed(), id: \.self) { number in Text("\(number)") }
                
            }
            .background(
                
                GeometryReader { proxy in
                    
                    Color.clear
                        .onAppear(perform: { backgroundSize = proxy.size.width })
                    
                })
            .listStyle(PlainListStyle())
            
        }
        .onChange(of: size, perform: { newValue in
            
            if let unwrappedValue: CGFloat = newValue, let backgroundSize: CGFloat = backgroundSize {
                paddingValue = (backgroundSize - unwrappedValue)/2.0
            }
 
        })
        
    }
}

Solution 2:[2]

Try this:

    VStack(spacing: 0) {
        Rectangle()
            .foregroundColor(.red)
            .frame(maxWidth : .infinity)
            .frame( height: 100)
            // .padding(.horizontal,20) // Remove the padding from here
        
        List {
            ForEach((1...20).reversed(), id: \.self) { number in
                Text("\(number)")
            }
            .listRowInsets(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 10)) // Set the EdgeInsets(leading: 0)
        }
        .listStyle(.plain) // Use a plain list style
    }
    .padding(.leading, 20) // Put the padding here

This gives you a plain list, and zeroing your edge inset puts it right up to the edge of the view. At that point, the rectangle and list are aligned. Then pad the VStack by 20.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 iosDev
Solution 2 Yrb