mirror of
https://github.com/VernissageApp/Vernissage.git
synced 2024-12-27 09:23:45 +01:00
Set correct image in image viewer.
This commit is contained in:
parent
fbdb1216dc
commit
13c4bc85c3
@ -22,6 +22,7 @@ struct StatusView: View {
|
||||
|
||||
@State private var statusViewModel: StatusViewModel?
|
||||
|
||||
@State private var selectedAttachmentId: String?
|
||||
@State private var exifCamera: String?
|
||||
@State private var exifExposure: String?
|
||||
@State private var exifCreatedDate: String?
|
||||
@ -32,6 +33,7 @@ struct StatusView: View {
|
||||
if let statusViewModel = self.statusViewModel {
|
||||
VStack (alignment: .leading) {
|
||||
ImagesCarousel(attachments: statusViewModel.mediaAttachments,
|
||||
selectedAttachmentId: $selectedAttachmentId,
|
||||
exifCamera: $exifCamera,
|
||||
exifExposure: $exifExposure,
|
||||
exifCreatedDate: $exifCreatedDate,
|
||||
@ -104,7 +106,7 @@ struct StatusView: View {
|
||||
})
|
||||
.fullScreenCover(isPresented: $showImageViewer, content: {
|
||||
if let statusViewModel = self.statusViewModel {
|
||||
ImagesViewer(statusViewModel: statusViewModel)
|
||||
ImagesViewer(statusViewModel: statusViewModel, selectedAttachmentId: selectedAttachmentId ?? String.empty())
|
||||
}
|
||||
})
|
||||
.task {
|
||||
@ -126,6 +128,7 @@ struct StatusView: View {
|
||||
}
|
||||
|
||||
self.statusViewModel = statusViewModel
|
||||
self.selectedAttachmentId = statusViewModel.mediaAttachments.first?.id ?? String.empty()
|
||||
self.firstLoadFinished = true
|
||||
|
||||
// If we have status in database then we can update data.
|
||||
|
@ -9,15 +9,16 @@ import SwiftUI
|
||||
struct ImagesCarousel: View {
|
||||
@State public var attachments: [AttachmentViewModel]
|
||||
@State private var height: Double = 0.0
|
||||
@State private var selectedAttachmentId = String.empty()
|
||||
@State private var selected = String.empty()
|
||||
|
||||
@Binding public var selectedAttachmentId: String?
|
||||
@Binding public var exifCamera: String?
|
||||
@Binding public var exifExposure: String?
|
||||
@Binding public var exifCreatedDate: String?
|
||||
@Binding public var exifLens: String?
|
||||
|
||||
var body: some View {
|
||||
TabView() {
|
||||
TabView(selection: $selected) {
|
||||
ForEach(attachments, id: \.id) { attachment in
|
||||
if let data = attachment.data, let image = UIImage(data: data) {
|
||||
Image(uiImage: image)
|
||||
@ -29,7 +30,9 @@ struct ImagesCarousel: View {
|
||||
}
|
||||
.frame(height: CGFloat(self.height))
|
||||
.tabViewStyle(PageTabViewStyle())
|
||||
.onChange(of: selectedAttachmentId, perform: { index in
|
||||
.onChange(of: selected, perform: { index in
|
||||
self.selectedAttachmentId = selected
|
||||
|
||||
if let attachment = attachments.first(where: { item in item.id == index }) {
|
||||
self.exifCamera = attachment.exifCamera
|
||||
self.exifExposure = attachment.exifExposure
|
||||
@ -38,7 +41,7 @@ struct ImagesCarousel: View {
|
||||
}
|
||||
})
|
||||
.onAppear {
|
||||
self.selectedAttachmentId = self.attachments.first?.id ?? String.empty()
|
||||
self.selected = self.attachments.first?.id ?? String.empty()
|
||||
self.calculateImageHeight()
|
||||
}
|
||||
}
|
||||
@ -63,6 +66,7 @@ struct ImagesCarousel: View {
|
||||
|
||||
struct ImagesCarousel_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ImagesCarousel(attachments: [], exifCamera: .constant(""), exifExposure: .constant(""), exifCreatedDate: .constant(""), exifLens: .constant(""))
|
||||
Text("")
|
||||
// ImagesCarousel(attachments: [], exifCamera: .constant(""), exifExposure: .constant(""), exifCreatedDate: .constant(""), exifLens: .constant(""))
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,14 @@ import SwiftUI
|
||||
|
||||
struct ImagesViewer: View {
|
||||
@State var statusViewModel: StatusViewModel
|
||||
@State var visible = false
|
||||
@State var selectedAttachmentId: String = String.empty()
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
// Opacity usied during fadein/fadeoff animations.
|
||||
@State private var opacity = 0.6
|
||||
|
||||
// Zoom.
|
||||
@State var zoomScale = 1.0
|
||||
@State private var zoomScale = 1.0
|
||||
|
||||
// Magnification.
|
||||
@State private var currentAmount = 0.0
|
||||
@ -20,53 +23,54 @@ struct ImagesViewer: View {
|
||||
|
||||
// Draging.
|
||||
@State private var currentOffset = CGSize.zero
|
||||
@State private var accumulatedOffset = CGSize.zero
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
if self.visible {
|
||||
TabView() {
|
||||
ForEach(statusViewModel.mediaAttachments, id: \.id) { attachment in
|
||||
if let data = attachment.data, let image = UIImage(data: data) {
|
||||
Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.tag(attachment.id)
|
||||
.offset(currentOffset)
|
||||
.scaleEffect((finalAmount + currentAmount) < 1.0 ? 1.0 : (finalAmount + currentAmount))
|
||||
.gesture((finalAmount + currentAmount) > 1.0 ? dragGesture : nil)
|
||||
.gesture(magnificationGesture)
|
||||
.gesture(doubleTapGesture)
|
||||
.gesture(tapGesture)
|
||||
}
|
||||
TabView(selection: $selectedAttachmentId) {
|
||||
ForEach(statusViewModel.mediaAttachments, id: \.id) { attachment in
|
||||
if let data = attachment.data, let image = UIImage(data: data) {
|
||||
Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.tag(attachment.id)
|
||||
.offset(x: currentOffset.width)
|
||||
.scaleEffect(finalAmount + currentAmount)
|
||||
.gesture((finalAmount + currentAmount) > 1.0 ? dragGesture : nil)
|
||||
.gesture(magnificationGesture)
|
||||
.gesture(doubleTapGesture)
|
||||
.gesture(tapGesture)
|
||||
}
|
||||
}
|
||||
.tabViewStyle(PageTabViewStyle())
|
||||
.overlay(alignment: .topTrailing, content: {
|
||||
Button {
|
||||
self.close()
|
||||
} label: {
|
||||
Image(systemName: "xmark")
|
||||
.foregroundColor(.white)
|
||||
.padding(8)
|
||||
.background(Color.white.opacity(0.25))
|
||||
.clipShape(Circle())
|
||||
}
|
||||
})
|
||||
}
|
||||
.opacity(self.opacity)
|
||||
.tabViewStyle(PageTabViewStyle())
|
||||
.overlay(alignment: .topTrailing, content: {
|
||||
Button {
|
||||
self.close()
|
||||
} label: {
|
||||
Image(systemName: "xmark")
|
||||
.foregroundColor(.white)
|
||||
.padding(8)
|
||||
.background(Color.mainTextColor.opacity(0.3))
|
||||
.clipShape(Circle())
|
||||
.padding()
|
||||
}
|
||||
})
|
||||
}
|
||||
.onAppear {
|
||||
withAnimation(.easeInOut) {
|
||||
self.visible = true
|
||||
withAnimation(.linear(duration: 0.2)) {
|
||||
opacity = 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func close() {
|
||||
withAnimation(.easeInOut) {
|
||||
self.visible = false
|
||||
withAnimation(.linear(duration: 0.3)) {
|
||||
opacity = 0.1
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.36) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
|
||||
withoutAnimation {
|
||||
dismiss()
|
||||
}
|
||||
@ -79,30 +83,50 @@ struct ImagesViewer: View {
|
||||
currentAmount = amount - 1
|
||||
}
|
||||
.onEnded { amount in
|
||||
finalAmount += currentAmount
|
||||
currentAmount = 0
|
||||
let finalMagnification = finalAmount + currentAmount
|
||||
|
||||
if finalMagnification < 1.0 {
|
||||
// When image is small we are returning to starting point.
|
||||
withAnimation(.default) {
|
||||
finalAmount = 1.0
|
||||
currentAmount = 0
|
||||
|
||||
// Also we have to move image to orginal position.
|
||||
currentOffset = CGSize.zero
|
||||
}
|
||||
} else if finalMagnification > 2.0 {
|
||||
// When image is magnified to much we are rturning to 1.5 maginification.
|
||||
withAnimation(.default) {
|
||||
finalAmount = 1.5
|
||||
currentAmount = 0
|
||||
}
|
||||
} else {
|
||||
finalAmount = finalMagnification
|
||||
currentAmount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var doubleTapGesture: some Gesture {
|
||||
TapGesture(count: 2)
|
||||
.onEnded { _ in
|
||||
currentOffset = CGSize.zero
|
||||
currentAmount = 0
|
||||
finalAmount = 1.0
|
||||
withAnimation {
|
||||
currentOffset = CGSize.zero
|
||||
currentAmount = 0
|
||||
finalAmount = 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dragGesture: some Gesture {
|
||||
DragGesture()
|
||||
.onChanged { amount in
|
||||
self.currentOffset = amount.translation
|
||||
self.currentOffset = CGSize(width: amount.translation.width + self.accumulatedOffset.width,
|
||||
height: amount.translation.height + self.accumulatedOffset.height)
|
||||
} .onEnded { amount in
|
||||
if (finalAmount + currentAmount) == 1.0 {
|
||||
withAnimation(.linear) {
|
||||
currentOffset = CGSize.zero
|
||||
}
|
||||
}
|
||||
self.currentOffset = CGSize(width: amount.translation.width + self.accumulatedOffset.width,
|
||||
height: amount.translation.height + self.accumulatedOffset.height)
|
||||
self.accumulatedOffset = self.currentOffset
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user