Skip to content

Instantly share code, notes, and snippets.

@manoamaro
Created February 14, 2021 10:30
Show Gist options
  • Save manoamaro/9da8c2b8e9e73c2863fd764e622ebbaf to your computer and use it in GitHub Desktop.
Save manoamaro/9da8c2b8e9e73c2863fd764e622ebbaf to your computer and use it in GitHub Desktop.
import SwiftUI
import UIKit
struct DataImageView<Placeholder: View>: View {
private final class ViewModel: ObservableObject {
@Published var image: UIImage?
private let data: Data
init(data: Data) {
self.data = data
}
func load(size: CGSize) {
DispatchQueue.global(qos: .userInitiated).async {
let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
let maxDimentionInPixels = max(size.width, size.height) * 2
let downsampledOptions = [kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceShouldCacheImmediately: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: maxDimentionInPixels] as CFDictionary
let imageSource = CGImageSourceCreateWithData(self.data as CFData, imageSourceOptions)!
let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampledOptions)!
DispatchQueue.main.async {
self.image = UIImage(cgImage: downsampledImage)
}
}
}
}
@StateObject private var viewModel: ViewModel
private let placeholder: Placeholder
init(data: Data, @ViewBuilder placeholder: () -> Placeholder) {
self.placeholder = placeholder()
self._viewModel = .init(wrappedValue: .init(data: data))
}
var body: some View {
GeometryReader { geometry in
Group {
if let uiImage = viewModel.image {
Image(uiImage: uiImage)
.resizable()
} else {
placeholder
}
}.onAppear(perform: {
viewModel.load(size: geometry.size)
})
}
.clipped()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment