Added remote image viewing
This commit is contained in:
parent
a601ca1bcc
commit
f03d664983
|
@ -2,6 +2,6 @@
|
||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "container:../..">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"object": {
|
||||||
|
"pins": [
|
||||||
|
{
|
||||||
|
"package": "URLImage",
|
||||||
|
"repositoryURL": "https://github.com/dmytro-anokhin/url-image.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "a48feef3ef91f573a5f55779502e07adb19943b8",
|
||||||
|
"version": "0.9.15"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"version": 1
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ let package = Package(
|
||||||
dependencies: [
|
dependencies: [
|
||||||
// Dependencies declare other packages that this package depends on.
|
// Dependencies declare other packages that this package depends on.
|
||||||
// .package(url: /* package url */, from: "1.0.0"),
|
// .package(url: /* package url */, from: "1.0.0"),
|
||||||
|
.package(url: "https://github.com/dmytro-anokhin/url-image.git", from: "0.9.15")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||||
|
|
|
@ -1,58 +1,153 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import URLImage
|
||||||
|
|
||||||
struct ImageViewer: View {
|
struct ImageViewerRemote: View {
|
||||||
@State var image: Image
|
@Binding var viewerShown: Bool
|
||||||
|
@Binding var imageURL: String
|
||||||
|
|
||||||
@State var dragOffset: CGSize = CGSize.zero
|
@State var dragOffset: CGSize = CGSize.zero
|
||||||
@State var dragOffsetPredicted: CGSize = CGSize.zero
|
@State var dragOffsetPredicted: CGSize = CGSize.zero
|
||||||
|
|
||||||
|
init(imageURL: Binding<String>, viewerShown: Binding<Bool>) {
|
||||||
|
_imageURL = imageURL
|
||||||
|
_viewerShown = viewerShown
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
VStack {
|
||||||
VStack {
|
if(viewerShown && imageURL.count > 0) {
|
||||||
HStack {
|
ZStack {
|
||||||
Button(action: { print("Close") }) {
|
VStack {
|
||||||
Image(systemName: "xmark")
|
HStack {
|
||||||
.foregroundColor(Color(UIColor.white))
|
Button(action: { self.viewerShown = false }) {
|
||||||
.font(.system(size: UIFontMetrics.default.scaledValue(for: 24)))
|
Image(systemName: "xmark")
|
||||||
}
|
.foregroundColor(Color(UIColor.white))
|
||||||
|
.font(.system(size: UIFontMetrics.default.scaledValue(for: 24)))
|
||||||
Spacer()
|
}
|
||||||
}
|
|
||||||
|
Spacer()
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
.padding()
|
|
||||||
.zIndex(2)
|
|
||||||
|
|
||||||
VStack {
|
|
||||||
self.image
|
|
||||||
.resizable()
|
|
||||||
.aspectRatio(contentMode: .fit)
|
|
||||||
.offset(x: self.dragOffset.width, y: self.dragOffset.height)
|
|
||||||
.rotationEffect(.init(degrees: Double(self.dragOffset.width / 30)))
|
|
||||||
.pinchToZoom()
|
|
||||||
.gesture(DragGesture()
|
|
||||||
.onChanged { value in
|
|
||||||
self.dragOffset = value.translation
|
|
||||||
self.dragOffsetPredicted = value.predictedEndTranslation
|
|
||||||
}
|
|
||||||
.onEnded { value in
|
|
||||||
print(abs(self.dragOffset.height) + abs(self.dragOffset.width))
|
|
||||||
print((abs(self.dragOffsetPredicted.height)) / (abs(self.dragOffset.height)))
|
|
||||||
print((abs(self.dragOffsetPredicted.width)) / (abs(self.dragOffset.width)))
|
|
||||||
|
|
||||||
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) {
|
|
||||||
print("would close")
|
|
||||||
}
|
}
|
||||||
self.dragOffset = .zero
|
|
||||||
|
Spacer()
|
||||||
}
|
}
|
||||||
)
|
.padding()
|
||||||
|
.zIndex(2)
|
||||||
|
|
||||||
|
VStack {
|
||||||
|
URLImage(URL(string: self.imageURL ?? "https://via.placeholder.com/300.png")!) { proxy in
|
||||||
|
proxy.image
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.offset(x: self.dragOffset.width, y: self.dragOffset.height)
|
||||||
|
.rotationEffect(.init(degrees: Double(self.dragOffset.width / 30)))
|
||||||
|
.pinchToZoom()
|
||||||
|
.gesture(DragGesture()
|
||||||
|
.onChanged { value in
|
||||||
|
self.dragOffset = value.translation
|
||||||
|
self.dragOffsetPredicted = value.predictedEndTranslation
|
||||||
|
}
|
||||||
|
.onEnded { value in
|
||||||
|
print(abs(self.dragOffset.height) + abs(self.dragOffset.width))
|
||||||
|
print((abs(self.dragOffsetPredicted.height)) / (abs(self.dragOffset.height)))
|
||||||
|
print((abs(self.dragOffsetPredicted.width)) / (abs(self.dragOffset.width)))
|
||||||
|
|
||||||
|
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) {
|
||||||
|
self.viewerShown = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.dragOffset = .zero
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.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))
|
||||||
|
.zIndex(1)
|
||||||
|
}
|
||||||
|
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 0.2)))
|
||||||
|
.onAppear() {
|
||||||
|
self.dragOffset = .zero
|
||||||
|
self.dragOffsetPredicted = .zero
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
||||||
.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))
|
|
||||||
.zIndex(1)
|
|
||||||
}
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ImageViewer: View {
|
||||||
|
@Binding var viewerShown: Bool
|
||||||
|
@Binding var image: Image
|
||||||
|
|
||||||
|
@State var dragOffset: CGSize = CGSize.zero
|
||||||
|
@State var dragOffsetPredicted: CGSize = CGSize.zero
|
||||||
|
|
||||||
|
init(image: Binding<Image>, viewerShown: Binding<Bool>) {
|
||||||
|
_image = image
|
||||||
|
_viewerShown = viewerShown
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
if(viewerShown) {
|
||||||
|
ZStack {
|
||||||
|
VStack {
|
||||||
|
HStack {
|
||||||
|
Button(action: { self.viewerShown = false }) {
|
||||||
|
Image(systemName: "xmark")
|
||||||
|
.foregroundColor(Color(UIColor.white))
|
||||||
|
.font(.system(size: UIFontMetrics.default.scaledValue(for: 24)))
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.zIndex(2)
|
||||||
|
|
||||||
|
VStack {
|
||||||
|
self.image
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.offset(x: self.dragOffset.width, y: self.dragOffset.height)
|
||||||
|
.rotationEffect(.init(degrees: Double(self.dragOffset.width / 30)))
|
||||||
|
.pinchToZoom()
|
||||||
|
.gesture(DragGesture()
|
||||||
|
.onChanged { value in
|
||||||
|
self.dragOffset = value.translation
|
||||||
|
self.dragOffsetPredicted = value.predictedEndTranslation
|
||||||
|
}
|
||||||
|
.onEnded { value in
|
||||||
|
print(abs(self.dragOffset.height) + abs(self.dragOffset.width))
|
||||||
|
print((abs(self.dragOffsetPredicted.height)) / (abs(self.dragOffset.height)))
|
||||||
|
print((abs(self.dragOffsetPredicted.width)) / (abs(self.dragOffset.width)))
|
||||||
|
|
||||||
|
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) {
|
||||||
|
self.viewerShown = false
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.dragOffset = .zero
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.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))
|
||||||
|
.zIndex(1)
|
||||||
|
}
|
||||||
|
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 0.2)))
|
||||||
|
.onAppear() {
|
||||||
|
self.dragOffset = .zero
|
||||||
|
self.dragOffsetPredicted = .zero
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue