Add tab type selection and content organization in QRCodeStyleView for improved user experience. Introduced TabType enum for managing styles, and refactored content areas for colors, dots, eyes, and logos, enhancing the overall layout and interaction.

main
v504 2 months ago
parent 4e509ce8e3
commit 03a145f7d9

@ -2,6 +2,32 @@ import SwiftUI
import QRCode
import CoreData
// MARK: -
enum TabType: String, CaseIterable {
case colors = "colors"
case dots = "dots"
case eyes = "eyes"
case logos = "logos"
var displayName: String {
switch self {
case .colors: return "颜色"
case .dots: return "点类型"
case .eyes: return "眼睛"
case .logos: return "Logo"
}
}
var iconName: String {
switch self {
case .colors: return "paintpalette"
case .dots: return "circle.grid.3x3"
case .eyes: return "eye"
case .logos: return "photo"
}
}
}
// MARK: -
struct QRCodeStyleView: View {
let qrCodeContent: String
@ -25,6 +51,9 @@ struct QRCodeStyleView: View {
@State private var qrCodeImage: UIImage?
@State private var isLoading = false
//
@State private var selectedTabType: TabType = .colors
// QRCode
private func createQRCodeDocument() -> QRCode.Document {
let d = try! QRCode.Document(engine: QRCodeEngineExternal())
@ -95,6 +124,69 @@ struct QRCodeStyleView: View {
// MARK: -
private var styleSelectionSection: some View {
VStack(spacing: 0) {
//
tabTypeSelection
//
contentArea
}
.background(Color(.systemGroupedBackground))
}
// MARK: -
private var tabTypeSelection: some View {
HStack(spacing: 0) {
ForEach(TabType.allCases, id: \.self) { tabType in
Button(action: {
selectedTabType = tabType
}) {
VStack(spacing: 4) {
Image(systemName: tabType.iconName)
.font(.system(size: 20))
.foregroundColor(selectedTabType == tabType ? .blue : .gray)
Text(tabType.displayName)
.font(.caption)
.foregroundColor(selectedTabType == tabType ? .blue : .gray)
}
.frame(maxWidth: .infinity)
.padding(.vertical, 12)
.background(
Rectangle()
.fill(selectedTabType == tabType ? Color.blue.opacity(0.1) : Color.clear)
)
}
}
}
.background(Color(.systemBackground))
.overlay(
Rectangle()
.frame(height: 1)
.foregroundColor(Color(.separator)),
alignment: .bottom
)
}
// MARK: -
private var contentArea: some View {
Group {
switch selectedTabType {
case .colors:
colorsContent
case .dots:
dotsContent
case .eyes:
eyesContent
case .logos:
logosContent
}
}
.frame(maxHeight: 400)
}
// MARK: -
private var colorsContent: some View {
ScrollView {
VStack(spacing: 24) {
//
@ -110,59 +202,21 @@ struct QRCodeStyleView: View {
colors: QRCodeColor.backgroundColors,
selectedColor: $selectedBackgroundColor
)
//
dotTypeSelectionSection
//
eyeTypeSelectionSection
// Logo
logoSelectionSection
}
.padding()
}
.background(Color(.systemGroupedBackground))
}
// MARK: -
private func colorSelectionSection(
title: String,
colors: [QRCodeColor],
selectedColor: Binding<QRCodeColor>
) -> some View {
VStack(alignment: .leading, spacing: 12) {
Text(title)
.font(.headline)
.foregroundColor(.primary)
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 6), spacing: 12) {
ForEach(colors, id: \.self) { color in
Button(action: {
selectedColor.wrappedValue = color
}) {
RoundedRectangle(cornerRadius: 8)
.fill(color.color)
.frame(height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(selectedColor.wrappedValue == color ? Color.blue : Color.clear, lineWidth: 3)
)
}
}
}
}
}
// MARK: -
private var dotTypeSelectionSection: some View {
VStack(alignment: .leading, spacing: 12) {
Text("点类型")
.font(.headline)
.foregroundColor(.primary)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 12) {
// MARK: -
private var dotsContent: some View {
ScrollView {
VStack(spacing: 16) {
Text("选择点类型")
.font(.title2)
.fontWeight(.bold)
.padding(.top)
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3), spacing: 16) {
ForEach(QRCodeDotType.allCases, id: \.self) { dotType in
Button(action: {
selectedDotType = dotType
@ -172,16 +226,16 @@ struct QRCodeStyleView: View {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
.frame(width: 60, height: 60)
.background(Color.white)
.cornerRadius(8)
.cornerRadius(12)
} else {
RoundedRectangle(cornerRadius: 8)
RoundedRectangle(cornerRadius: 12)
.fill(Color.gray.opacity(0.3))
.frame(width: 40, height: 40)
.frame(width: 60, height: 60)
.overlay(
Text("?")
.font(.caption)
.font(.title2)
.foregroundColor(.secondary)
)
}
@ -189,14 +243,15 @@ struct QRCodeStyleView: View {
Text(dotType.displayName)
.font(.caption)
.foregroundColor(.primary)
.multilineTextAlignment(.center)
}
.padding(8)
.padding(12)
.background(
RoundedRectangle(cornerRadius: 12)
RoundedRectangle(cornerRadius: 16)
.fill(selectedDotType == dotType ? Color.blue.opacity(0.1) : Color.clear)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(selectedDotType == dotType ? Color.blue : Color.clear, lineWidth: 2)
RoundedRectangle(cornerRadius: 16)
.stroke(selectedDotType == dotType ? Color.blue : Color.clear, lineWidth: 3)
)
)
}
@ -207,15 +262,16 @@ struct QRCodeStyleView: View {
}
}
// MARK: -
private var eyeTypeSelectionSection: some View {
VStack(alignment: .leading, spacing: 12) {
Text("眼睛类型")
.font(.headline)
.foregroundColor(.primary)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 12) {
// MARK: -
private var eyesContent: some View {
ScrollView {
VStack(spacing: 16) {
Text("选择眼睛类型")
.font(.title2)
.fontWeight(.bold)
.padding(.top)
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3), spacing: 16) {
ForEach(QRCodeEyeType.allCases, id: \.self) { eyeType in
Button(action: {
selectedEyeType = eyeType
@ -225,16 +281,16 @@ struct QRCodeStyleView: View {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
.frame(width: 60, height: 60)
.background(Color.white)
.cornerRadius(8)
.cornerRadius(12)
} else {
RoundedRectangle(cornerRadius: 8)
RoundedRectangle(cornerRadius: 12)
.fill(Color.gray.opacity(0.3))
.frame(width: 40, height: 40)
.frame(width: 60, height: 60)
.overlay(
Text("?")
.font(.caption)
.font(.title2)
.foregroundColor(.secondary)
)
}
@ -242,14 +298,15 @@ struct QRCodeStyleView: View {
Text(eyeType.displayName)
.font(.caption)
.foregroundColor(.primary)
.multilineTextAlignment(.center)
}
.padding(8)
.padding(12)
.background(
RoundedRectangle(cornerRadius: 12)
RoundedRectangle(cornerRadius: 16)
.fill(selectedEyeType == eyeType ? Color.blue.opacity(0.1) : Color.clear)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(selectedEyeType == eyeType ? Color.blue : Color.clear, lineWidth: 2)
RoundedRectangle(cornerRadius: 16)
.stroke(selectedEyeType == eyeType ? Color.blue : Color.clear, lineWidth: 3)
)
)
}
@ -260,40 +317,42 @@ struct QRCodeStyleView: View {
}
}
// MARK: - Logo
private var logoSelectionSection: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Logo")
.font(.headline)
.foregroundColor(.primary)
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 12) {
// MARK: - Logo
private var logosContent: some View {
ScrollView {
VStack(spacing: 16) {
Text("选择Logo")
.font(.title2)
.fontWeight(.bold)
.padding(.top)
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 3), spacing: 16) {
// Logo
Button(action: {
selectedLogo = nil
}) {
VStack(spacing: 8) {
RoundedRectangle(cornerRadius: 8)
RoundedRectangle(cornerRadius: 12)
.fill(Color.gray.opacity(0.3))
.frame(width: 40, height: 40)
.frame(width: 60, height: 60)
.overlay(
Text("")
.font(.caption)
.font(.title2)
.foregroundColor(.secondary)
)
Text("无Logo")
.font(.caption)
.foregroundColor(.primary)
.multilineTextAlignment(.center)
}
.padding(8)
.padding(12)
.background(
RoundedRectangle(cornerRadius: 12)
RoundedRectangle(cornerRadius: 16)
.fill(selectedLogo == nil ? Color.blue.opacity(0.1) : Color.clear)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(selectedLogo == nil ? Color.blue : Color.clear, lineWidth: 2)
RoundedRectangle(cornerRadius: 16)
.stroke(selectedLogo == nil ? Color.blue : Color.clear, lineWidth: 3)
)
)
}
@ -308,16 +367,16 @@ struct QRCodeStyleView: View {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
.frame(width: 60, height: 60)
.background(Color.white)
.cornerRadius(8)
.cornerRadius(12)
} else {
RoundedRectangle(cornerRadius: 8)
RoundedRectangle(cornerRadius: 12)
.fill(Color.gray.opacity(0.3))
.frame(width: 40, height: 40)
.frame(width: 60, height: 60)
.overlay(
Text("?")
.font(.caption)
.font(.title2)
.foregroundColor(.secondary)
)
}
@ -325,14 +384,15 @@ struct QRCodeStyleView: View {
Text(logo.displayName)
.font(.caption)
.foregroundColor(.primary)
.multilineTextAlignment(.center)
}
.padding(8)
.padding(12)
.background(
RoundedRectangle(cornerRadius: 12)
RoundedRectangle(cornerRadius: 16)
.fill(selectedLogo == logo ? Color.blue.opacity(0.1) : Color.clear)
.overlay(
RoundedRectangle(cornerRadius: 12)
.stroke(selectedLogo == logo ? Color.blue : Color.clear, lineWidth: 2)
RoundedRectangle(cornerRadius: 16)
.stroke(selectedLogo == logo ? Color.blue : Color.clear, lineWidth: 3)
)
)
}
@ -343,6 +403,37 @@ struct QRCodeStyleView: View {
}
}
// MARK: -
private func colorSelectionSection(
title: String,
colors: [QRCodeColor],
selectedColor: Binding<QRCodeColor>
) -> some View {
VStack(alignment: .leading, spacing: 12) {
Text(title)
.font(.headline)
.foregroundColor(.primary)
LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 6), spacing: 12) {
ForEach(colors, id: \.self) { color in
Button(action: {
selectedColor.wrappedValue = color
}) {
RoundedRectangle(cornerRadius: 8)
.fill(color.color)
.frame(height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(selectedColor.wrappedValue == color ? Color.blue : Color.clear, lineWidth: 3)
)
}
}
}
}
}
// MARK: -
private func saveQRCode() {
guard let qrCodeImage = qrCodeImage else { return }

Loading…
Cancel
Save