swiftuisdwebimagesdwebimageswiftui

How to make an image fade in when loaded using SDWebImageSwiftUI


I am using the following code in a LazyVGrid to load images from a firebase bucket with SDWebImageSwiftUI and they show, but they don't fade in nicely and show suddenly:

import SDWebImageSwiftUI

struct ExploreCategoryImageView: View {
    
    let category: StoreMainCategory
    
    var body: some View {
        ZStack (alignment:.leading){
            WebImage(url: URL(string:"\(category.image)"))
                .resizable()
                .transition(.fade(duration: 0.5))
                .scaledToFill()
        }
        .frame(height:125)
        .contentShape(Rectangle())
        .background (Color.white)
        .cornerRadius(7.5)
        .shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 5)
        .padding(.horizontal,7.5)
    }
} 

I have the latest version of SDWebImageSwiftUI 2.2.6 and SDWebImage 5.19.0, but was wondering, do I need to do something special in the init() or AppDelegate of the app to make the images fade in nicely when loaded?


Solution

  • According to the documentation for WebImage, it is possible to add an .onSuccess callback to the image, which is called when it has been loaded successfully. So it might be possible to use this to update a state variable that controls the opacity:

    @State private var imageLoaded = false
    
    WebImage(url: URL(string:"\(category.image)"))
        .resizable()
        .scaledToFill()
        .opacity(imageLoaded ? 1 : 0)
        .animation(.easeInOut(duration: 0.5), value: imageLoaded)
        .onSuccess { _ in
            imageLoaded = true
        }
    

    The API also lets you set an indicator or a placeholder, so you could try experimenting with these too, in case they provide another way of providing a fade effect.

    If you use the opacity approach as above, then an alternative way to show a placeholder would be to show an image in a lower layer of your ZStack. However, if you don't know the aspect ratio of the image you are loading then it would be best to hide the placeholder at the same time as you reveal the loaded image, otherwise parts of the placeholder image may "stick out" from below the loaded image. Then again, if you are scaling to fill, it shouldn't be an issue... assuming the loaded image does not include any transparent parts.