简体   繁体   中英

SwiftUI setting individual backgrounds for list Elements that fill the element

So I'm trying to make a list where the background of each element is an image that completely fills the element and I'm struggling to get it to completely fill the area.

here's some simple example code showing what I have so far.

struct Event {
    var description:String = "description"
    var title:String = "Title"
    var view:Image
}

struct RowView: View {
    @State var event:Event
    
    var body: some View {
        VStack {
            Text(event.title)
                .font(.headline)
            Text(event.description)
                .font(.subheadline)
        }
    }
}
struct ContentView: View {
    @State var events:[Event] = [Event(view: Image("blue")),Event( view: Image("red")),Event( view: Image("green"))]
    @State private var editMode = EditMode.inactive
    
    var body: some View {
        NavigationView {
            List() {
                ForEach(events.indices, id: \.self) { elementID in
                    NavigationLink(
                        destination: RowView(event: events[elementID])) {
                    RowView(event: events[elementID])
                    }
                        .background(events[elementID].view)
                        .clipped()
                }
            }
            .listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
            .navigationTitle("Events")
            .navigationBarItems(leading: EditButton())
            .environment(\.editMode, $editMode)
        }
    }
}

This is what's produced by the code as you can see there is a border around the background image still. 在此处输入图片说明

I don't know what your images are, but seems that should not be important. Here is a demo on replicated code using colors.

Tested with Xcode 12.1 / iOS 14.1

演示

Modified parts (important highlighted in comments)

struct Event {
    var description:String = "description"
    var title:String = "Title"
    var view:Color
}

struct ContentView: View {
    @State var events:[Event] = [Event(view: .blue),Event( view: .red),Event( view: .green)]
    @State private var editMode = EditMode.inactive
    
    var body: some View {
        NavigationView {
            List() {
                ForEach(events.indices, id: \.self) { elementID in
                    events[elementID].view.overlay(     // << this !!
                       NavigationLink(
                        destination: RowView(event: events[elementID])) {
                           RowView(event: events[elementID])
                    })
                }
                .listRowInsets(EdgeInsets())   // << this !!
            }
            .listStyle(PlainListStyle())    // << and this !!
            .navigationTitle("Events")
            .navigationBarItems(leading: EditButton())
            .environment(\.editMode, $editMode)
        }
    }
}

This works:

struct RowView: View {
    @State var event:Event

    var body: some View {
        VStack(alignment: .leading) {
            Text(event.title)
                .font(.headline)
            Text(event.description)
                .font(.subheadline)
        }
        .padding(10)
        .foregroundColor(.yellow)
    }
}
struct ContentView: View {
    @State var events:[Event] = [Event(view: Image("blue")),Event( view: Image("red")),Event( view: Image("green"))]
    @State private var editMode = EditMode.inactive

    var body: some View {
        NavigationView {
            List() {
                ForEach(events.indices, id: \.self) { elementID in
                    NavigationLink(
                        destination: RowView(event: events[elementID])) {
                        RowView(event: events[elementID])
                    }
                    .background(events[elementID].view
                                    .resizable()
                                    .aspectRatio(contentMode: .fill)
                    )

                    .clipped()
                }
                .listRowInsets(EdgeInsets())
            }
            .listStyle(PlainListStyle())
            .navigationTitle("Events")
            .navigationBarItems(leading: EditButton())
            .environment(\.editMode, $editMode)
        }
    }
}

This is a derivative of Asperi's answer, so you can accept his answer, but this works with images, and no overlay. Tested on Xcode 12.1, IOS 14.1.

Here is an image where I grabbed arbitrary sized images for "red", "green", and "blue" from Goggle. I took the liberty of changing the row text to yellow so it would show up better.

示例结果

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