5

I am using a List to dynamically create multiple instances of a view, however, when using list padding is added to the left and right of the child views and I can't remove it. I've tried using .listRowInset, but that has yielded no visible effect.

I have created a PostView that works as desired. I am using a 'PostsView' to dynamically generate multiple PostView instances.

The am trying to get the image in the PostView to touch the edges of the screen within the PostsView.

PostView

import SwiftUI



struct PostView: View {
    var post: Post

    var body: some View {

        VStack {
            HStack {
                Text(post.songInfo.album).font(.title)
                Spacer()
                Text(post.songInfo.artist)
            }.padding()

            Image(post.songInfo.albumArtUrl)
                .resizable()
                .aspectRatio(UIImage(named: "sweetner")!.size,  contentMode: .fit)
            HStack {
                Image("plus-icon")
                Spacer()
                Image("comment-icon")
                Spacer()
                Image("headset-icon")
            }.padding()

            HStack {
                Text(post.user.userName)
                Spacer()
                Text(post.textContent)
            }.padding()


        }
    }
}

PostsView

import SwiftUI

struct PostsView: View {
   @ObservedObject var fbVM = FirebaseInfo()

    var body: some View {

       List(fbVM.visiblePosts) { post in
            PostView(post: post)
       }

    }
}

struct PostsView_Previews: PreviewProvider {
    static var previews: some View {
        PostsView()
    }
}

enter image description here

1

2 Answers 2

15

Update

Take a look at this answer

It looks like .listRowInsets doesn't work for rows in a List that is initialised with content

So you can do this if you change your code slightly. First you need to remove the padding from the post view so the text will go to the edge (if that's what you want):

struct PostView: View {
  let placeholder = UIImage(named: "arianaGrande")!
  var post: Post

  var body: some View {
    VStack {
      HStack {
        Text(post.album).font(.title)
        Spacer()
        Text(post.artist)
      }// .padding() -- This padding adds space before "Sweetener and after Ariana Grande

      Image(uiImage: placeholder)
        .resizable()
        .aspectRatio(placeholder.size,  contentMode: .fit)
      HStack {
        Image("plus-icon")
        Spacer()
        Image("comment-icon")
        Spacer()
        Image("headset-icon")
      }.padding()

      HStack {
        Text(post.username)
        Spacer()
        Text(post.textContent)
      }//.padding() -- Same thing here.
    }
  }
}

struct PostView_Previews: PreviewProvider {
  static var previews: some View {
    PostView(post: Post(
      artist: "Ariana Grande",
      album: "Sweetener",
      albumArtUrl: "",
      username: "DoesData",
      textContent: "Text Content"
      )
    )
  }
} 

Then you can initialize your list slightly differently to remove the spacing.

struct PostsView: View {
  var posts = [
    Post(
      artist: "Ariana Grande",
      album: "Sweetener",
      albumArtUrl: "",
      username: "DoesData",
      textContent: "Text Content"
    )
  ]

  var body: some View {
    List {
      ForEach(posts) { post in
        PostView(post: post)
          .listRowInsets(EdgeInsets())
      }
    }
  }
}

struct Post: Identifiable {
  let id = UUID()
  let artist: String
  let album: String
  let albumArtUrl: String
  let username: String
  let textContent: String
}

struct PostsView_Previews: PreviewProvider {
  static var previews: some View {
    PostsView()
  }
}

Result:

enter image description here

Original Answer

It looks like you can adjust padding on the list itself to remove the leading and trailing margins.

import SwiftUI

struct PostsView: View {
   @ObservedObject var fbVM = FirebaseInfo()

    var body: some View {

       List(fbVM.visiblePosts) { post in
            PostView(post: post)
       }.padding(.horizontal, -20) // -20 seems to make it go edge to edge

    }
}

struct PostsView_Previews: PreviewProvider {
    static var previews: some View {
        PostsView()
    }
}

You also might need to adjust the padding inside PostView for the text like this Text("Title").font(.title).padding(.leading, -10) This seems more elaborate than it should be, but it appears to work.

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

3 Comments

this is not a proper way on how you should handle dynamic paddings or something that may change
I agree. I've updated my answer to include a better method.
It is well know workaround and as far as I know it is the only one that works. Thanks for the update. Upvoting now.
9

There are several spacings that you can change in a list. Take a look at this color-coded map and pick the one that fits your needs:

List(1...100, id: \.self) { item in
    Text("\(item)")
        .padding() // 🟣 comment to remove PURPLE padding
        .background(Color.yellow)
        // .listRowInsets(EdgeInsets()) // 🔵 uncomment to remove BLUE inset
}
// .listStyle(.plain) // 🟢 uncomment to remove GREEN inset
// .listStyle(.grouped) // 🔴 uncomment to remove RED inset

Demo

RTL-Demo


Important note:

It looks like .listRowInsets doesn't work for rows in a List that is initialized with content. So you need to use ForEach inside the list like:

var body: some View {
    List {
        ForEach(...) {
            Text("String")
                .listRowInsets(EdgeInsets())
        }
    }
}

2 Comments

That doesn't appear to have any affect when applied to the view within the list
This Answer is what you're looking for.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.