feat(ios): 封面图改为卡片+底部弹窗选择 + 必填加红星

- 封面图改为全宽卡片,点击弹出底部 confirmationDialog
- 选项:"从相册选择" / "取消"
- 名称和描述字段加红色 * 必填标识

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-05-28 10:56:55 +08:00
parent 3547b6cef6
commit 11c0fe42b7

View File

@ -8,31 +8,42 @@ struct CreateLibraryPage: View {
@State private var isCreating = false; @State private var isUploadingCover = false
@State private var coverKey: String?; @State private var coverImage: UIImage?
@State private var showCoverPicker = false; @State private var coverPhotoItem: PhotosPickerItem?
@State private var showCoverSheet = false
var body: some View {
ZStack { Color.zxBg0.ignoresSafeArea(); VStack(spacing: 0) {
ScrollView { VStack(spacing: 20) {
//
VStack(alignment: .leading, spacing: 8) {
Text("封面图(可选,正方形)").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035)
Button { showCoverPicker = true } label: {
//
Button { showCoverSheet = true } label: {
ZStack {
RoundedRectangle(cornerRadius: 14).fill(Color.zxFill004)
.overlay(RoundedRectangle(cornerRadius: 14).stroke(style: StrokeStyle(lineWidth: 1.5, dash: [6, 4])).foregroundColor(Color.zxBorder01))
.frame(width: 160, height: 160)
.overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1))
if let img = coverImage {
Image(uiImage: img).resizable().scaledToFill().frame(width: 160, height: 160).clipShape(RoundedRectangle(cornerRadius: 14))
Image(uiImage: img).resizable().scaledToFill().frame(height: 140).clipShape(RoundedRectangle(cornerRadius: 14))
} else {
VStack(spacing: 8) {
Image(systemName: "photo.badge.plus").font(.system(size: 28)).foregroundColor(Color.zxF04)
Text("点击上传").font(.system(size: 13)).foregroundColor(Color.zxF04)
Image(systemName: "photo.on.rectangle.angled").font(.system(size: 28)).foregroundColor(Color.zxF04)
Text("添加封面图").font(.system(size: 13, weight: .medium)).foregroundColor(Color.zxF04)
Text("从相册选择").font(.system(size: 11)).foregroundColor(Color.zxF03)
}
}
if isUploadingCover { RoundedRectangle(cornerRadius: 14).fill(Color.black.opacity(0.4)).frame(width: 160, height: 160); ProgressView().tint(.white) }
if isUploadingCover { RoundedRectangle(cornerRadius: 14).fill(Color.black.opacity(0.4)); ProgressView().tint(.white) }
}
}.disabled(isUploadingCover)
.frame(height: 140)
}
.disabled(isUploadingCover)
.confirmationDialog("封面图", isPresented: $showCoverSheet) {
Button("从相册选择") { showCoverPicker = true }
Button("取消", role: .cancel) {}
}
VStack(alignment: .leading, spacing: 8) {
HStack(spacing: 2) { Text("知识库名称").font(.system(size: 12, weight: .semibold)); Text("*").foregroundColor(.red) }.foregroundColor(Color.zxF035)
TextField("例如:机器学习", text: $name).font(.system(size: 15)).tint(Color.zxPurple).padding(.horizontal, 16).frame(height: 52).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1))
}
VStack(alignment: .leading, spacing: 8) {
HStack(spacing: 2) { Text("描述").font(.system(size: 12, weight: .semibold)); Text("*").foregroundColor(.red) }.foregroundColor(Color.zxF035)
TextEditor(text: $desc).frame(minHeight: 80).scrollContentBackground(.hidden).padding(8).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1))
}
VStack(alignment: .leading, spacing: 8) { Text("知识库名称").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextField("例如:机器学习", text: $name).font(.system(size: 15)).tint(Color.zxPurple).padding(.horizontal, 16).frame(height: 52).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
VStack(alignment: .leading, spacing: 8) { Text("描述").font(.system(size: 12, weight: .semibold)).foregroundColor(Color.zxF035); TextEditor(text: $desc).frame(minHeight: 80).scrollContentBackground(.hidden).padding(8).background(Color.zxFill004).clipShape(RoundedRectangle(cornerRadius: 14)).overlay(RoundedRectangle(cornerRadius: 14).stroke(Color.zxBorder008, lineWidth: 1)) }
Button {
guard !name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty,
!desc.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }