Skip to content

Instantly share code, notes, and snippets.

@snowzurfer
Created January 30, 2023 05:15
Show Gist options
  • Save snowzurfer/61d59730f31b86098c323f0b5a709872 to your computer and use it in GitHub Desktop.
Save snowzurfer/61d59730f31b86098c323f0b5a709872 to your computer and use it in GitHub Desktop.
SwiftUI animated Skeleton Image and demo usage with NukeUI Image.
//
// LazyImageWithLoadingStates.swift
//
// Copyright © 2023 Alberto Taiuti. All rights reserved.
//
import os
import NukeUI
import SwiftUI
import SFSafeSymbols
struct LazyImageWithLoadingStates: View {
let imageRequest: ImageRequest
static private let log = Logger.makeLogger(type: LazyImageWithLoadingStates.self)
var body: some View {
LazyImage(request: imageRequest) { state in
if let image = state.image {
// Displays the loaded image.
image
} else if state.error != nil {
VStack {
SwiftUI.Image(systemSymbol: SFSymbol.exclamationmarkTriangleFill)
.font(.body)
Text("ERROR_RETRIEVING_IMAGE")
.font(.caption)
.multilineTextAlignment(.center)
.padding(.horizontal, 4)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
// Acts as a placeholder.
GraySkeletonImage()
}
}
.onFailure { error in
Self.log.error("Failed image download task, error: \(error)")
}
}
}
//
// SkeletonImage.swift
//
// Copyright © 2023 Alberto Taiuti. All rights reserved.
//
import SwiftUI
struct SkeletonImage: View {
let startColor: Color
let endColor: Color
let animationDuration: CGFloat
@State private var color = Color(.systemGray6)
var body: some View {
Rectangle()
.fill(color)
.onAppear {
color = startColor
withAnimation(.easeInOut(duration: animationDuration).repeatForever()) {
color = endColor
}
}
}
}
struct GraySkeletonImage: View {
var body: some View {
// Arrived at empirically
SkeletonImage(startColor: Color(.systemGray6), endColor: Color(.systemGray4), animationDuration: 0.9)
}
}
struct SkeletonImage_Previews: PreviewProvider {
static var previews: some View {
GraySkeletonImage()
.frame(width: 180, height: 300)
.cornerRadius(10)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment