Files
ios/Xuxucheck/XuXuCheck/Mine/Views/MineView.swift
T
admin d6aeede2bc 导入 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。
2026-09-23 14:17:31 +08:00

285 lines
8.9 KiB
Swift

//
// MineView.swift
// XuXuCheck
//
// Created by henseycai on 2025/6/11.
//
import SwiftUI
struct MineView: View {
@State var isDeleted = false
@State var isPinned = false
@State var isLoginModalPresented = false
@State var isMyselfPresented = false
@Environment(LoginViewModel.self) var loginViewModel: LoginViewModel
@Environment(LoginStatus.self) var loginStatus
var body: some View {
NavigationStack {
List {
profile
menu
setting
}
.listStyle(.automatic)
.navigationTitle("Profile")
}
}
var profile: some View {
VStack(spacing: 8) {
if !loginStatus.isLogin {
Group{
Image(systemName: "person")
.symbolVariant(.circle.fill)
.font(.system(size: 32))
.symbolRenderingMode(.palette)
.foregroundStyle(.blue, .blue.opacity(0.4))
.padding()
.background(Circle().fill(.ultraThinMaterial))
.background(
HexagonView()
.offset(x: -50, y: -100)
)
.background(
BlobView()
.offset(x: 200, y: 0)
.scaleEffect(0.6)
)
Text("Sign In").font(.title.weight(.semibold))
}.onTapGesture {
isLoginModalPresented.toggle()
}
} else {
Group{
//AsyncImage
CachedAsyncImage(
url: URL(string: API.imageUrl + Storage.shared.useravatar)
) { image in
image
.resizable()
.frame(width: 40, height: 40)
.cornerRadius(45)
} placeholder: {
ZStack {
Color.secondary.opacity(0.25)
Image(systemName: "person")
.imageScale(.large)
.blendMode(.overlay)
}
}
.symbolVariant(.circle.fill)
.font(.system(size: 32))
.symbolRenderingMode(.palette)
.foregroundStyle(.blue, .blue.opacity(0.4))
.padding()
.background(Circle().fill(.ultraThinMaterial))
.background(
HexagonView()
.offset(x: -50, y: -100)
)
.background(
BlobView()
.offset(x: 200, y: 0)
.scaleEffect(0.6)
)
Text(Storage.shared.username).font(.title.weight(.semibold))
Text(Storage.shared.email)
.foregroundColor(.secondary)
}.onTapGesture {
isMyselfPresented.toggle()
}
}
}
.fullScreenCover(isPresented: $isLoginModalPresented) { //sheet
if !loginStatus.isLogin {
LoginView()
}
}
.fullScreenCover(isPresented: $isMyselfPresented) { //sheet
XuXuWebView(currentUrl: API.webMyAccountUrl + GetGeneralRequestParams())
}
.frame(maxWidth: .infinity)
.padding()
}
@State var iScanQrPresented = false
@State private var scannedCode: String?
@State var isColorPresented = false
@State var isIntroPresented = false
@State var isTutorPresented = false
@State var isAboutPresented = false
@State var isSettingPresented = false
// @State var isAnimating = false
var menu: some View {
Section {
//
// Image(systemName: "face.smiling")
// .offset(x: isAnimating ? 200 : 0)
// .animation(.easeInOut(duration: 5).repeatForever(autoreverses: false), value: isAnimating)
// .onAppear{
// isAnimating.toggle()
// }
Button(
action: {
iScanQrPresented.toggle()
},
label: {
NavigationLink(
value: UUID(),
label: {
Label("qrcode", systemImage: "qrcode.viewfinder")
}
)
}
).buttonStyle(PlainButtonStyle())
.sheet(isPresented: $iScanQrPresented) {
CodeScannerView(codeTypes: [.qr]) { response in
if case let .success(result) = response {
scannedCode = result.string
iScanQrPresented = false
}
}
}
//Text(scannedCode ?? "")
//
// NavigationLink {
// //Text("Quality Control")
// } label: {
// Label("Quality Control", systemImage: "creditcard")
// }.buttonStyle(PlainButtonStyle())
Button(
action: {
isColorPresented.toggle()
},
label: {
NavigationLink(
value: UUID(),
label: {
Label("Color Card", systemImage: "lanyardcard")
}
)
}
).buttonStyle(PlainButtonStyle())
.fullScreenCover(isPresented: $isColorPresented) {
XuXuWebView(currentUrl: API.webColorimetricCardUrl + GetGeneralRequestParams())
}
//ImagePickerView()
Button(
action: {
isIntroPresented.toggle()
},
label: {
NavigationLink(
value: UUID(),
label: {
Label("Introduction", systemImage: "questionmark.folder")
}
)
}
).buttonStyle(PlainButtonStyle())
.fullScreenCover(isPresented: $isIntroPresented) {
XuXuWebView(currentUrl: API.webProductIntroductionUrl + GetGeneralRequestParams())
}
//UnitView()
// Button(
// action: {
// isTutorPresented.toggle()
// },
// label: {
// NavigationLink(
// value: UUID(),
// label: {
// Label("Tutorial", systemImage: "questionmark")
// }
// )
// }
// ).buttonStyle(PlainButtonStyle())
// .fullScreenCover(isPresented: $isTutorPresented) {
// XuXuWebView(currentUrl: API.webManualUrl + GetGeneralRequestParams())
// }
Button(
action: {
isAboutPresented.toggle()
},
label: {
NavigationLink(
value: UUID(),
label: {
Label("About Us", systemImage: "info.circle")
}
)
}
).buttonStyle(PlainButtonStyle())
.fullScreenCover(isPresented: $isAboutPresented) {
XuXuWebView(currentUrl: API.webAboutUsUrl + GetGeneralRequestParams())
}
}
.accentColor(.secondary)
.listRowSeparatorTint(.blue)
.listRowSeparator(.hidden)
}
var setting: some View {
Section {
Button(
action: {
isSettingPresented.toggle()
},
label: {
NavigationLink(
value: UUID(),
label: {
Label("Settings", systemImage: "gear")
}
)
}
).buttonStyle(PlainButtonStyle())
.fullScreenCover(isPresented: $isSettingPresented) {
XuXuWebView(currentUrl: API.webSettingUrl + GetGeneralRequestParams())
// ImagePickerView()
}
}
.accentColor(.secondary)
.listRowSeparatorTint(.blue)
.listRowSeparator(.hidden)
}
}
#Preview {
MineView()
}