import SwiftUI #if canImport(UIKit) import UIKit #endif struct A1ViewfinderView: View { var onShoot: () -> Void var onClose: () -> Void @State private var dotPulse = false var body: some View { GeometryReader { geometry in ZStack { Color(red: 0.04, green: 0.047, blue: 0.04).ignoresSafeArea() mockCameraPreview(screenHeight: geometry.size.height) VStack { HStack { Button(action: onClose) { Image(systemName: "xmark") .font(.system(size: 18, weight: .semibold)) .foregroundStyle(Color.white) .frame(width: 36, height: 36) } Spacer() } .padding(.horizontal, 6) .padding(.top, 50) topHint Spacer() } SmartFramer() .allowsHitTesting(false) .ignoresSafeArea() identifiedPill .padding(.top, geometry.size.height * 0.62 - 20) VStack { Spacer() bottomControls } } } #if os(iOS) .statusBarHidden(false) #endif .preferredColorScheme(.dark) } private func mockCameraPreview(screenHeight: CGFloat) -> some View { RadialGradient( colors: [Color.white.opacity(0.05), Color.clear], center: .init(x: 0.5, y: 0.3), startRadius: 20, endRadius: 400 ) .overlay(alignment: .center) { VStack(alignment: .leading, spacing: 6) { Text("总胆固醇 TC 5.42 mmol/L").opacity(0.65) Text("甘油三酯 TG 1.78 mmol/L").opacity(0.65) Text("低密度脂蛋白 3.84 mmol/L ↑").fontWeight(.semibold).opacity(1) Text("高密度脂蛋白 1.21 mmol/L").opacity(0.65) Text("载脂蛋白 A1 1.42 g/L").opacity(0.45) Text("载脂蛋白 B 1.04 g/L").opacity(0.45) } .font(.system(size: 11, design: .monospaced)) .foregroundStyle(Tj.Palette.text) .padding(.vertical, 20) .padding(.horizontal, 18) .frame(maxWidth: .infinity, alignment: .leading) .background(Color(red: 0.96, green: 0.93, blue: 0.87).opacity(0.92)) .clipShape(RoundedRectangle(cornerRadius: 4, style: .continuous)) .rotationEffect(.degrees(-1.2)) .shadow(color: .black.opacity(0.45), radius: 15, x: 0, y: 12) .padding(.horizontal, 24) .padding(.vertical, screenHeight * 0.20) } } private var topHint: some View { Text("对准异常的那一行就好 · 不用拍整张") .font(.system(size: 12)) .tracking(0.5) .foregroundStyle(Color.white.opacity(0.92)) .padding(.horizontal, 14) .padding(.vertical, 7) .background(Capsule().fill(Color(red: 0.08, green: 0.11, blue: 0.094).opacity(0.7))) .padding(.top, 6) } private var identifiedPill: some View { HStack(spacing: 6) { Circle() .fill(Tj.Palette.paper) .frame(width: 6, height: 6) .opacity(dotPulse ? 1 : 0.35) Text("AI 已识别到 1 项指标") .font(.system(size: 11)) .tracking(0.5) } .foregroundStyle(Tj.Palette.paper) .padding(.horizontal, 10) .padding(.vertical, 4) .background(Capsule().fill(Color(red: 0.37, green: 0.47, blue: 0.31).opacity(0.85))) .onAppear { withAnimation(.easeInOut(duration: 2.2).repeatForever(autoreverses: true)) { dotPulse.toggle() } } } private var bottomControls: some View { HStack { CircleIconButton(icon: "bolt.fill", size: 44) { } Spacer() Button(action: onShoot) { ZStack { Circle().fill(Tj.Palette.ink) Circle().strokeBorder(Tj.Palette.paper, lineWidth: 4) } .frame(width: 72, height: 72) .overlay( Circle().strokeBorder(Color.white.opacity(0.2), lineWidth: 1) .frame(width: 76, height: 76) ) } .buttonStyle(.plain) Spacer() CircleIconButton(icon: "photo.on.rectangle", size: 44) { } } .padding(.horizontal, 32) .padding(.bottom, 40) } } private struct CircleIconButton: View { let icon: String let size: CGFloat let action: () -> Void var body: some View { Button(action: action) { ZStack { Circle().fill(Color.white.opacity(0.12)) Image(systemName: icon) .font(.system(size: 18, weight: .medium)) .foregroundStyle(Tj.Palette.paper) } .frame(width: size, height: size) } .buttonStyle(.plain) } }