@@ -15,12 +15,16 @@ public struct ImageViewerRemote: View {
15
15
@State var dragOffset : CGSize = CGSize . zero
16
16
@State var dragOffsetPredicted : CGSize = CGSize . zero
17
17
18
+ @ObservedObject var loader : ImageLoader
19
+
18
20
public init ( imageURL: Binding < String > , viewerShown: Binding < Bool > , httpHeaders: [ String : String ] ? = nil , aspectRatio: Binding < CGFloat > ? = nil , disableCache: Bool ? = nil ) {
19
21
_imageURL = imageURL
20
22
_viewerShown = viewerShown
21
23
_httpHeaders = State ( initialValue: httpHeaders)
22
24
_disableCache = State ( initialValue: disableCache)
23
25
self . aspectRatio = aspectRatio
26
+
27
+ loader = ImageLoader ( url: imageURL, httpHeaders: httpHeaders)
24
28
}
25
29
26
30
func getURLRequest( url: String , headers: [ String : String ] ? ) -> URLRequest {
@@ -92,10 +96,30 @@ public struct ImageViewerRemote: View {
92
96
. zIndex ( 1 )
93
97
}
94
98
else {
95
- AsyncImage (
96
- url: getURLRequest ( url: self . imageURL, headers: self . httpHeaders) ,
97
- placeholder: Text ( " Loading ... " ) , aspectRatio: self . aspectRatio, dragOffset: self . $dragOffset, dragOffsetPredicted: self . $dragOffsetPredicted, viewerShown: self . $viewerShown
98
- )
99
+ if loader. image != nil {
100
+ Image ( uiImage: loader. image!)
101
+ . resizable ( )
102
+ . aspectRatio ( self . aspectRatio? . wrappedValue, contentMode: . fit)
103
+ . offset ( x: self . dragOffset. width, y: self . dragOffset. height)
104
+ . rotationEffect ( . init( degrees: Double ( self . dragOffset. width / 30 ) ) )
105
+ . pinchToZoom ( )
106
+ . gesture ( DragGesture ( )
107
+ . onChanged { value in
108
+ self . dragOffset = value. translation
109
+ self . dragOffsetPredicted = value. predictedEndTranslation
110
+ }
111
+ . onEnded { value in
112
+ 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 ) {
113
+ self . viewerShown = false
114
+ return
115
+ }
116
+ self . dragOffset = . zero
117
+ }
118
+ )
119
+ }
120
+ else {
121
+ Text ( " Loading... " )
122
+ }
99
123
}
100
124
}
101
125
}
@@ -269,19 +293,43 @@ extension View {
269
293
270
294
class ImageLoader : ObservableObject {
271
295
@Published var image : UIImage ?
272
- private let url : URLRequest
296
+ private let url : Binding < String >
297
+ private let headers : [ String : String ] ?
273
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
+ }
274
319
275
- init ( url: URLRequest ) {
320
+ init ( url: Binding < String > , httpHeaders : [ String : String ] ? ) {
276
321
self . url = url
322
+ self . headers = httpHeaders
323
+
324
+ load ( )
277
325
}
278
326
279
327
deinit {
280
328
cancellable? . cancel ( )
281
329
}
282
330
283
331
func load( ) {
284
- cancellable = URLSession . shared. dataTaskPublisher ( for: url)
332
+ cancellable = URLSession . shared. dataTaskPublisher ( for: getURLRequest ( url: self . url . wrappedValue , headers : self . headers ) )
285
333
. map { UIImage ( data: $0. data) }
286
334
. replaceError ( with: nil )
287
335
. receive ( on: DispatchQueue . main)
@@ -292,57 +340,3 @@ class ImageLoader: ObservableObject {
292
340
cancellable? . cancel ( )
293
341
}
294
342
}
295
-
296
- struct AsyncImage < Placeholder: View > : View {
297
- @ObservedObject private var loader : ImageLoader
298
-
299
- private let placeholder : Placeholder ?
300
-
301
- var aspectRatio : Binding < CGFloat > ?
302
- @Binding var dragOffset : CGSize
303
- @Binding var dragOffsetPredicted : CGSize
304
- @Binding var viewerShown : Bool
305
-
306
- init ( url: URLRequest , placeholder: Placeholder ? = nil , aspectRatio: Binding < CGFloat > ? , dragOffset: Binding < CGSize > , dragOffsetPredicted: Binding < CGSize > , viewerShown: Binding < Bool > ) {
307
- loader = ImageLoader ( url: url)
308
- self . placeholder = placeholder
309
- self . aspectRatio = aspectRatio
310
- _dragOffset = dragOffset
311
- _dragOffsetPredicted = dragOffsetPredicted
312
- _viewerShown = viewerShown
313
- }
314
-
315
- var body : some View {
316
- image
317
- . onAppear ( perform: loader. load)
318
- . onDisappear ( perform: loader. cancel)
319
- }
320
-
321
- private var image : some View {
322
- Group {
323
- if loader. image != nil {
324
- Image ( uiImage: loader. image!)
325
- . resizable ( )
326
- . aspectRatio ( self . aspectRatio? . wrappedValue, contentMode: . fit)
327
- . offset ( x: self . dragOffset. width, y: self . dragOffset. height)
328
- . rotationEffect ( . init( degrees: Double ( self . dragOffset. width / 30 ) ) )
329
- . pinchToZoom ( )
330
- . gesture ( DragGesture ( )
331
- . onChanged { value in
332
- self . dragOffset = value. translation
333
- self . dragOffsetPredicted = value. predictedEndTranslation
334
- }
335
- . onEnded { value in
336
- 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 ) {
337
- self . viewerShown = false
338
- return
339
- }
340
- self . dragOffset = . zero
341
- }
342
- )
343
- } else {
344
- placeholder
345
- }
346
- }
347
- }
348
- }
0 commit comments