-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRemoteImage.swift
More file actions
67 lines (59 loc) · 1.7 KB
/
Copy pathRemoteImage.swift
File metadata and controls
67 lines (59 loc) · 1.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//
// RemoteImage.swift
//
// Created by Hovik Melikyan on 17.04.23.
//
import SwiftUI
struct RemoteImage<P: View, I: View>: View {
let url: URL?
@ViewBuilder let content: (Image) -> I
@ViewBuilder let placeholder: (Error?) -> P
@State private var uiImage: UIImage?
@State private var error: Error?
var body: some View {
ZStack {
if let image = uiImage.map({ Image(uiImage: $0) }) {
content(image)
}
else if let error {
placeholder(error)
}
else {
placeholder(nil)
}
}
.onChange(of: url, initial: true) { oldValue, newValue in
// Try sync load first
if let newValue, let image = ImageCache.loadFromMemory(newValue) {
uiImage = image
return
}
uiImage = nil
error = nil
if let newValue {
Task {
do {
// Now try loading from disk or downloading remote
self.uiImage = try await ImageCache.request(newValue)
}
catch {
self.error = error
}
}
}
}
}
}
#Preview {
let url = URL(string: "https://images.unsplash.com/photo-1513051265668-0ebab31671ae")!
return RemoteImage(url: url) { image in
image
.resizable()
.aspectRatio(contentMode: .fill)
.ignoresSafeArea()
} placeholder: { error in
Text(error?.localizedDescription ?? "LOADING...")
.font(.caption)
.padding()
}
}