```
refactor: 重命名项目名称从"体己"到"康康" 将整个项目的目录结构从"体己"重命名为"康康",包括所有源代码文件、 资源文件、测试文件以及Xcode项目配置文件。此更改涉及项目中所有的 文件路径和应用入口点(App/TijiApp.swift → App/KangkangApp.swift)。 ```
This commit is contained in:
159
康康/Features/Quick/A1ViewfinderView.swift
Normal file
159
康康/Features/Quick/A1ViewfinderView.swift
Normal file
@@ -0,0 +1,159 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user