导入 XuXuCheck 工程(iOS 干化学尿液试纸分析 App)

从桌面工程复制而来,作为本仓库的 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。
This commit is contained in:
2026-09-23 14:17:31 +08:00
commit d6aeede2bc
901 changed files with 327267 additions and 0 deletions
+141
View File
@@ -0,0 +1,141 @@
//
// TabBar.swift
// XuXuCheck
//
// Created by henseycai on 2025/6/11.
//
import SwiftUI
struct TabBar: View {
@AppStorage("selectedTab") var selectedTab: Tab = .home
@State var color : Color = .teal
@State var tabItemWidth: CGFloat = 0
var body: some View {
ZStack(alignment: .bottom) {
GeometryReader { proxy in
let hasHomeIndicator: Bool = proxy.safeAreaInsets.bottom > 20
HStack {
buttons
}
.padding(.horizontal, 8)
.padding(.top, 14)
.frame(height: hasHomeIndicator ? 88 : 62, alignment: .top)
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: hasHomeIndicator ? 34 : 0, style: .continuous))
.background(
background
)
.overlay(
overlay
)
.strokeStyle(cornerRadius: hasHomeIndicator ? 34 : 0)
.frame(maxHeight: .infinity, alignment: .bottom)
.ignoresSafeArea()
}
}
}
var buttons: some View {
ForEach(tabItems) { item in
Button {
withAnimation(.spring(response: 0.3, dampingFraction: 0.6)) {
selectedTab = item.tab
color = item.color
}
} label: {
VStack(spacing: 0) {
Image(systemName: item.icon)
.symbolVariant(.fill)
.font(.body.bold())
.frame(width: 44, height: 29)
Text(item.text)
.font(.caption2)
.lineLimit(1)
}
.frame(maxWidth: .infinity)
}
.foregroundStyle(selectedTab == item.tab ? .primary : .secondary)
.blendMode(selectedTab == item.tab ? .overlay : .normal)
.overlay(
GeometryReader { proxy in
Color.clear.preference(key: TabPreferenceKey.self, value: proxy.size.width)
}
)
.onPreferenceChange(TabPreferenceKey.self) { value in
tabItemWidth = value
}
}
}
var background : some View {
HStack {
if selectedTab == .mine { Spacer() }
if selectedTab == .members {
Spacer()
}
if selectedTab == .records {
Spacer()
Spacer()
}
Circle().fill(color).frame(width: tabItemWidth)
if selectedTab == .home {
Spacer()
}
if selectedTab == .members {
Spacer()
Spacer()
}
if selectedTab == .records {
Spacer()
}
}
.padding(.horizontal, 8)
}
var overlay: some View {
HStack {
if selectedTab == .mine { Spacer() }
if selectedTab == .members {
Spacer()
}
if selectedTab == .records {
Spacer()
Spacer()
}
Rectangle()
.fill(color)
.frame(width: 28, height: 5)
.cornerRadius(3)
.frame(width: tabItemWidth)
.frame(maxHeight: .infinity, alignment: .top)
if selectedTab == .home {
Spacer()
}
if selectedTab == .members {
Spacer()
Spacer()
}
if selectedTab == .records {
Spacer()
}
}
.padding(.horizontal, 8)
}
}
struct TabBar_Previews: PreviewProvider {
static var previews: some View {
Group {
TabBar()
.previewInterfaceOrientation(.landscapeLeft)
TabBar()
.preferredColorScheme(.dark)
}
}
}