d6aeede2bc
从桌面工程复制而来,作为本仓库的 Xuxucheck/ 子目录。 为控制仓库体积做了两处删减: - 移除 Frameworks/opencv2.xcframework 下的两个 visionOS 切片 (xros-arm64、xros-arm64-simulator,合计约 106 MB),并同步删掉该 xcframework 内 Info.plist 里对应的两条 AvailableLibraries 记录, 只保留 ios-arm64 与 ios-arm64_x86_64-simulator。 - 移除全部 .DS_Store 与 xcuserdata/。 已用 xcodebuild 从本目录完整编译验证:BUILD SUCCEEDED, ProcessXCFramework 以 --platform ios 成功选中框架,产物含 3699 个 cv:: 符号 (OpenCV 确实链入),嵌入 framework 3 个,与移除无用 pod 之后的状态一致。 仓库约 206 MB,其中 OpenCV 203 MB、其余源码与依赖约 3 MB。
132 lines
4.2 KiB
Swift
132 lines
4.2 KiB
Swift
//
|
|
// TimerCountView.swift
|
|
// XuXuCheck
|
|
//
|
|
// Created by henseycai on 2025/7/25.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct TimerCountView: View {
|
|
|
|
@State var timeRemaining: Int = 60
|
|
@State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
|
|
@Binding var canStartScan: Bool
|
|
|
|
@Environment(\.dismiss) private var dissmiss
|
|
@Environment(CameraViewModel.self) private var cameraViewModel
|
|
|
|
var body: some View {
|
|
let bgcolor = Color(hex: 0x2449f1)
|
|
let bgcolor2 = Color(hex: 0x1638d9)
|
|
VStack{
|
|
|
|
HStack {
|
|
|
|
Image(systemName: "arrow.backward")
|
|
.frame(width: 50, height: 50)
|
|
.foregroundColor(.primary)
|
|
.strokeStyle(cornerRadius: 15)
|
|
.onTapGesture {
|
|
dissmiss()
|
|
}
|
|
|
|
Text("Countdown Timer").font(.headline).frame(maxWidth: .infinity, alignment: .center)
|
|
}
|
|
|
|
ZStack {
|
|
// Digit Counter
|
|
Text(
|
|
"\(timeRemaining)s"
|
|
)
|
|
.font(.system(size: 56, weight: .bold))
|
|
|
|
// Circle Counter
|
|
Group {
|
|
Circle()
|
|
.rotation(.degrees(-90))
|
|
.stroke(
|
|
bgcolor.opacity(0.3),
|
|
style: StrokeStyle(lineWidth: 12, dash: [CGFloat.pi / 2, CGFloat.pi * 3.5])
|
|
)
|
|
Circle()
|
|
.trim(
|
|
from: 0,
|
|
to: (CGFloat(timeRemaining).truncatingRemainder(dividingBy: 60) - 0.25) / 60
|
|
)
|
|
.rotation(.degrees(-90))
|
|
.stroke(
|
|
bgcolor2.opacity(0.8),
|
|
style: StrokeStyle(lineWidth: 12, dash: [CGFloat.pi / 2, CGFloat.pi * 3.5])
|
|
)
|
|
}
|
|
.frame(width: 240, height: 240)
|
|
}.onReceive(timer){ _ in
|
|
if timeRemaining > 0 {
|
|
// if timeremaining is greater than zero subtract 1
|
|
timeRemaining -= 1
|
|
}
|
|
else
|
|
{
|
|
//else reset it to 5 if its equal to 0. this will save it from a negative num
|
|
timeRemaining = 60
|
|
self.timer.upstream.connect().cancel()
|
|
|
|
|
|
cameraViewModel.startSession()
|
|
|
|
|
|
canStartScan = true
|
|
|
|
//dissmiss()
|
|
}
|
|
}
|
|
|
|
|
|
Text("Urine chemical reaction needs one minute about. Please put strip on white paper towel.").foregroundStyle(.primary)
|
|
.font(.title2).frame(maxWidth: .infinity, alignment: .center)
|
|
.offset(x:20,y:100)
|
|
|
|
///-----------------------------
|
|
Spacer()
|
|
|
|
HStack{
|
|
Button(action: {
|
|
timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
|
|
timeRemaining = 60
|
|
}, label: {
|
|
Text("Reset Timer")
|
|
.frame(width: 120)
|
|
.padding()
|
|
.foregroundColor(.white)
|
|
.background(Color.gray)
|
|
.cornerRadius(10)
|
|
})
|
|
|
|
Spacer()
|
|
|
|
Button(action: {
|
|
self.timer.upstream.connect().cancel()
|
|
|
|
cameraViewModel.startSession()
|
|
|
|
canStartScan = true
|
|
|
|
}, label: {
|
|
Text("Scan Now")
|
|
.frame(width: 120)
|
|
.padding()
|
|
.foregroundColor(.white)
|
|
.background(Color.blue)
|
|
.cornerRadius(10)
|
|
})
|
|
|
|
}
|
|
|
|
}.padding(50)
|
|
|
|
|
|
}
|
|
}
|
|
|