Skip to content

Commit 42b7fbf

Browse files
authored
Merge pull request #15 from Jake-Short/add-no-cache-option
Add option to disable cache
2 parents e6a0739 + 989ab09 commit 42b7fbf

File tree

1 file changed

+113
-23
lines changed

1 file changed

+113
-23
lines changed

Sources/ImageViewerRemote/ImageViewerRemote.swift

+113-23
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
import SwiftUI
22
import UIKit
33
import URLImage
4+
import Combine
45

56
@available(iOS 13.0, *)
67
public struct ImageViewerRemote: View {
78
@Binding var viewerShown: Bool
89
@Binding var imageURL: String
910
@State var httpHeaders: [String: String]?
11+
@State var disableCache: Bool?
1012

1113
var aspectRatio: Binding<CGFloat>?
1214

1315
@State var dragOffset: CGSize = CGSize.zero
1416
@State var dragOffsetPredicted: CGSize = CGSize.zero
1517

16-
public init(imageURL: Binding<String>, viewerShown: Binding<Bool>, httpHeaders: [String: String]? = nil, aspectRatio: Binding<CGFloat>? = nil) {
18+
@ObservedObject var loader: ImageLoader
19+
20+
public init(imageURL: Binding<String>, viewerShown: Binding<Bool>, httpHeaders: [String: String]? = nil, aspectRatio: Binding<CGFloat>? = nil, disableCache: Bool? = nil) {
1721
_imageURL = imageURL
1822
_viewerShown = viewerShown
1923
_httpHeaders = State(initialValue: httpHeaders)
24+
_disableCache = State(initialValue: disableCache)
2025
self.aspectRatio = aspectRatio
26+
27+
loader = ImageLoader(url: imageURL, httpHeaders: httpHeaders)
2128
}
2229

2330
func getURLRequest(url: String, headers: [String: String]?) -> URLRequest {
@@ -62,31 +69,59 @@ public struct ImageViewerRemote: View {
6269
.zIndex(2)
6370

6471
VStack {
65-
URLImage(getURLRequest(url: self.imageURL, headers: self.httpHeaders)) { proxy in
66-
proxy.image
67-
.resizable()
68-
.aspectRatio(self.aspectRatio?.wrappedValue, contentMode: .fit)
69-
.offset(x: self.dragOffset.width, y: self.dragOffset.height)
70-
.rotationEffect(.init(degrees: Double(self.dragOffset.width / 30)))
71-
.pinchToZoom()
72-
.gesture(DragGesture()
73-
.onChanged { value in
74-
self.dragOffset = value.translation
75-
self.dragOffsetPredicted = value.predictedEndTranslation
76-
}
77-
.onEnded { value in
78-
if((abs(self.dragOffset.height) + abs(self.dragOffset.width) > 570) || ((abs(self.dragOffsetPredicted.height)) / (abs(self.dragOffset.height)) > 3) || ((abs(self.dragOffsetPredicted.width)) / (abs(self.dragOffset.width))) > 3) {
79-
self.viewerShown = false
80-
return
72+
if(self.disableCache == nil || self.disableCache == false) {
73+
URLImage(getURLRequest(url: self.imageURL, headers: self.httpHeaders)) { proxy in
74+
proxy.image
75+
.resizable()
76+
.aspectRatio(self.aspectRatio?.wrappedValue, contentMode: .fit)
77+
.offset(x: self.dragOffset.width, y: self.dragOffset.height)
78+
.rotationEffect(.init(degrees: Double(self.dragOffset.width / 30)))
79+
.pinchToZoom()
80+
.gesture(DragGesture()
81+
.onChanged { value in
82+
self.dragOffset = value.translation
83+
self.dragOffsetPredicted = value.predictedEndTranslation
84+
}
85+
.onEnded { value in
86+
if((abs(self.dragOffset.height) + abs(self.dragOffset.width) > 570) || ((abs(self.dragOffsetPredicted.height)) / (abs(self.dragOffset.height)) > 3) || ((abs(self.dragOffsetPredicted.width)) / (abs(self.dragOffset.width))) > 3) {
87+
self.viewerShown = false
88+
return
89+
}
90+
self.dragOffset = .zero
8191
}
82-
self.dragOffset = .zero
83-
}
84-
)
92+
)
93+
}
94+
}
95+
else {
96+
if loader.image != nil {
97+
Image(uiImage: loader.image!)
98+
.resizable()
99+
.aspectRatio(self.aspectRatio?.wrappedValue, contentMode: .fit)
100+
.offset(x: self.dragOffset.width, y: self.dragOffset.height)
101+
.rotationEffect(.init(degrees: Double(self.dragOffset.width / 30)))
102+
.pinchToZoom()
103+
.gesture(DragGesture()
104+
.onChanged { value in
105+
self.dragOffset = value.translation
106+
self.dragOffsetPredicted = value.predictedEndTranslation
107+
}
108+
.onEnded { value in
109+
if((abs(self.dragOffset.height) + abs(self.dragOffset.width) > 570) || ((abs(self.dragOffsetPredicted.height)) / (abs(self.dragOffset.height)) > 3) || ((abs(self.dragOffsetPredicted.width)) / (abs(self.dragOffset.width))) > 3) {
110+
self.viewerShown = false
111+
return
112+
}
113+
self.dragOffset = .zero
114+
}
115+
)
116+
}
117+
else {
118+
Text(":/")
119+
}
85120
}
86-
.frame(maxWidth: .infinity, maxHeight: .infinity)
87-
.background(Color(red: 0.12, green: 0.12, blue: 0.12, opacity: (1.0 - Double(abs(self.dragOffset.width) + abs(self.dragOffset.height)) / 1000)).edgesIgnoringSafeArea(.all))
88-
.zIndex(1)
89121
}
122+
.frame(maxWidth: .infinity, maxHeight: .infinity)
123+
.background(Color(red: 0.12, green: 0.12, blue: 0.12, opacity: (1.0 - Double(abs(self.dragOffset.width) + abs(self.dragOffset.height)) / 1000)).edgesIgnoringSafeArea(.all))
124+
.zIndex(1)
90125
}
91126
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 0.2)))
92127
.onAppear() {
@@ -250,3 +285,58 @@ extension View {
250285
self.modifier(PinchToZoom())
251286
}
252287
}
288+
289+
290+
291+
292+
293+
294+
class ImageLoader: ObservableObject {
295+
@Published var image: UIImage?
296+
private let url: Binding<String>
297+
private let headers: [String: String]?
298+
private var cancellable: AnyCancellable?
299+
300+
func getURLRequest(url: String, headers: [String: String]?) -> URLRequest {
301+
let url = URL(string: url)!
302+
var request = URLRequest(url: url)
303+
request.httpMethod = "GET"
304+
305+
if(headers != nil) {
306+
for (key, value) in headers! {
307+
print("adding header: \(key): \(value)")
308+
request.addValue("\(value)", forHTTPHeaderField: "\(key)")
309+
}
310+
311+
print("headers found, requesting URL image with headers: \(request.allHTTPHeaderFields)")
312+
return request;
313+
}
314+
else {
315+
print("headers nil, requesting URL image with request: \(request)")
316+
return request;
317+
}
318+
}
319+
320+
init(url: Binding<String>, httpHeaders: [String: String]?) {
321+
self.url = url
322+
self.headers = httpHeaders
323+
324+
load()
325+
}
326+
327+
deinit {
328+
cancellable?.cancel()
329+
}
330+
331+
func load() {
332+
cancellable = URLSession.shared.dataTaskPublisher(for: getURLRequest(url: self.url.wrappedValue, headers: self.headers))
333+
.map { UIImage(data: $0.data) }
334+
.replaceError(with: nil)
335+
.receive(on: DispatchQueue.main)
336+
.assign(to: \.image, on: self)
337+
}
338+
339+
func cancel() {
340+
cancellable?.cancel()
341+
}
342+
}

0 commit comments

Comments
 (0)