SDWebImage / SDWebImageSwiftUI

SwiftUI Image loading and Animation framework powered by SDWebImage
https://sdwebimage.github.io/SDWebImageSwiftUI
MIT License
2.16k stars 223 forks source link

How to make image aspect fill in a LazyVGrid? #142

Closed YuantongL closed 3 years ago

YuantongL commented 3 years ago

I'm trying to make a grid with 2 columns, each has 1:1 images. I can't get it to work with the image to aspectfill the container.

struct VibeGalleryView: View {

    let vibeImages: [URL]
    let isLoading: Bool

    var body: some View {
        if isLoading {
            ProgressView()
        } else {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: .infinity, maximum: .infinity)),
                                GridItem(.adaptive(minimum: .infinity, maximum: .infinity))]) {
                ForEach(0..<vibeImages.count) { index in
                    WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))
                        .resizable()
                        .placeholder { Color.gray }
                        .aspectRatio(CGSize(width: 100, height: 100), contentMode: .fit)
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                        .cornerRadius(10)
                        .clipped()
                }
            }
        }
    }
}

This code above will make this following preview, it does fill the container but it stretched the image: image

struct VibeGalleryView: View {

    let vibeImages: [URL]
    let isLoading: Bool

    var body: some View {
        if isLoading {
            ProgressView()
        } else {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: .infinity, maximum: .infinity)),
                                GridItem(.adaptive(minimum: .infinity, maximum: .infinity))]) {
                ForEach(0..<vibeImages.count) { index in
                    WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))
                        .resizable()
                        .placeholder { Color.gray }
                        .scaledToFit()
                        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
                        .aspectRatio(CGSize(width: 100, height: 100), contentMode: .fit)
                        .cornerRadius(10)
                        .clipped()
                }
            }
        }
    }
}

This above code will result this following preview, it remains the ratio but but it does not fill the container: image

Maybe I'm mis-using something, but please help point that out if that's the case.

james-william-r commented 3 years ago

Hey @YuantongL, it looks like both of your examples have the their aspect set to fit. Try using the .scaledToFill modifier, or change the contentMode in your first example to .fill. 😊

YuantongL commented 3 years ago

I am able to achieve that using GeometryReader like this

struct VibeGalleryView: View {
    var body: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: .infinity, maximum: .infinity)),
                                GridItem(.adaptive(minimum: .infinity, maximum: .infinity))]) {
                ForEach(0..<10) { index in
                    GeometryReader { geo in
                        WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))
                            .resizable()
                            .scaledToFill()
                            .frame(width: geo.size.width, height: geo.size.height)
                            .cornerRadius(10)
                            .clipped()
                    }
                    .aspectRatio(1, contentMode: .fill)
                }
            }
        }
    }
}

Images remain 1:1 ratio and aspect fit
Screen Shot 2021-03-12 at 1 08 55 PM