1// FullScreenImageView.swift
2// SophaxChat
3//
4// Pinch-to-zoom full-screen image viewer with a dismiss button.
5
6import SwiftUI
7
8struct FullScreenImageView: View {
9 @Environment(\.dismiss) private var dismiss
10 let imageData: Data
11
12 @State private var scale: CGFloat = 1.0
13 @State private var offset: CGSize = .zero
14
15 private var uiImage: UIImage? { UIImage(data: imageData) }
16
17 var body: some View {
18 ZStack(alignment: .topTrailing) {
19 Color.black.ignoresSafeArea()
20
21 if let img = uiImage {
22 Image(uiImage: img)
23 .resizable()
24 .scaledToFit()
25 .scaleEffect(scale)
26 .offset(offset)
27 .gesture(
28 MagnificationGesture()
29 .onChanged { v in scale = max(1, v) }
30 .onEnded { _ in
31 withAnimation(.spring()) {
32 if scale < 1.2 { scale = 1; offset = .zero }
33 }
34 }
35 )
36 .simultaneousGesture(
37 DragGesture()
38 .onChanged { v in
39 guard scale > 1 else { return }
40 offset = v.translation
41 }
42 .onEnded { _ in
43 if scale <= 1 {
44 withAnimation(.spring()) { offset = .zero }
45 }
46 }
47 )
48 .onTapGesture(count: 2) {
49 withAnimation(.spring()) {
50 scale = scale > 1 ? 1 : 2
51 offset = .zero
52 }
53 }
54 }
55
56 Button {
57 dismiss()
58 } label: {
59 Image(systemName: "xmark.circle.fill")
60 .font(.system(size: 28))
61 .foregroundStyle(.white.opacity(0.85))
62 .padding(16)
63 }
64 }
65 .statusBarHidden()
66 }
67}