Created
February 14, 2021 10:30
-
-
Save manoamaro/9da8c2b8e9e73c2863fd764e622ebbaf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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