From 35962c644e70c9943e4db703486e53ecaffa21a6 Mon Sep 17 00:00:00 2001 From: jinyaqiu Date: Fri, 15 Aug 2025 15:35:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=BE=E7=BD=AE=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=8A=A8=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UserInterfaceState.xcuserstate | Bin 55011 -> 64279 bytes wake/ContentView.swift | 342 ++++++++---------- wake/Extensions/ViewExtensions.swift | 22 ++ wake/View/Components/SheetModal.swift | 6 +- wake/View/Components/UserProfileModal.swift | 135 +++++++ wake/View/Owner/SettingsView.swift | 286 ++++++--------- 6 files changed, 434 insertions(+), 357 deletions(-) create mode 100644 wake/Extensions/ViewExtensions.swift create mode 100644 wake/View/Components/UserProfileModal.swift diff --git a/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate b/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate index 69f8b3eed5cedf18c9f3f3a515741c8446d1a732..553e11ce0f25748db60ef54db9369383c049d1cb 100644 GIT binary patch literal 64279 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 a<+O#`^8I;ojhFXl2(tef{^NHm{Qm&%3i$y5 delta 26772 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 SYv2C=O6HRP{r|svI{g=o_0d`Y diff --git a/wake/ContentView.swift b/wake/ContentView.swift index 268de74..74d4525 100644 --- a/wake/ContentView.swift +++ b/wake/ContentView.swift @@ -1,228 +1,194 @@ import SwiftUI -// 自定义从左向右的过渡动画 +// MARK: - 自定义过渡动画 extension AnyTransition { + /// 创建从左向右的滑动过渡动画 static var slideFromLeading: AnyTransition { .asymmetric( - insertion: .move(edge: .trailing).combined(with: .opacity), - removal: .move(edge: .leading).combined(with: .opacity) + insertion: .move(edge: .trailing).combined(with: .opacity), // 从右侧滑入 + removal: .move(edge: .leading).combined(with: .opacity) // 向左侧滑出 ) } } -// 1. 定义路由 +// MARK: - 路由定义 enum Route: Hashable { - case settings + case settings // 设置页面路由 } +// MARK: - 主视图 struct ContentView: View { - @State private var showModal = false - @State private var showSettings = false - @State private var navigationPath = NavigationPath() - @State private var contentOffset: CGFloat = 0 + // MARK: - 状态属性 + @State private var showModal = false // 控制用户资料弹窗显示 + @State private var showSettings = false // 控制设置页面显示 + @State private var navigationPath = NavigationPath() // 导航路径 + @State private var contentOffset: CGFloat = 0 // 内容偏移量 - var body: some View { + // MARK: - 主体视图 + var body: some View { NavigationStack(path: $navigationPath) { - // 添加动画修饰符到 NavigationStack + // 调试信息 let _ = Self._printChanges() - let _ = print("Navigation path changed: \(navigationPath)") + let _ = print("导航路径已更新: \(navigationPath)") + // 主内容区域 ZStack { + // 主内容视图 VStack { VStack(spacing: 20) { - // This spacer ensures content stays below the status bar + // 状态栏占位 Spacer().frame(height: UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0) - // 顶部栏 + + // 顶部导航栏 - 左侧设置按钮 HStack { - Spacer() - Button(action: { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - showModal = true - } - }) { + // 设置按钮 + Button(action: showUserProfile) { Image(systemName: "gearshape") .font(.title2) .padding() } + Spacer() // 将按钮推到左侧 } Spacer() - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color(.systemBackground)) - .offset(x: showModal ? UIScreen.main.bounds.width * 0.35 : 0) - .animation(.spring(response: 0.5, dampingFraction: 0.8), value: showModal) - .edgesIgnoringSafeArea(.all) - } - // 添加半透明遮罩层 - if showModal { - Color.black.opacity(0.4) - .edgesIgnoringSafeArea(.all) - .onTapGesture { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - showModal = false - } - } - .transition(.opacity) - } - - // Modal with animation - will be pushed off-screen by SettingsView - SlideInModal(isPresented: $showModal, onDismiss: { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - showModal = false - } - }) { - // Modal content - // Modal content with offset for SettingsView - VStack(spacing: 20) { - // 用户信息区域 - HStack(alignment: .center, spacing: 16) { - // 头像 - Image(systemName: "person.circle.fill") - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: 60, height: 60) - .foregroundColor(.blue) - .clipShape(Circle()) - // 姓名和ID - VStack(alignment: .leading, spacing: 4) { - Text("用户名") - .font(.headline) - .foregroundColor(.primary) + // 内容列表 + List { + Section(header: Text("我的收藏")) { + ForEach(1...5, id: \.self) { item in + HStack { + Image(systemName: "photo") + .foregroundColor(.blue) + .frame(width: 40, height: 40) + .background(Color.blue.opacity(0.1)) + .cornerRadius(8) + + VStack(alignment: .leading, spacing: 4) { + Text("项目 \(item)") + .font(.headline) + Text("这是第\(item)个项目的描述") + .font(.subheadline) + .foregroundColor(.secondary) + } + + Spacer() + + Image(systemName: "chevron.right") + .foregroundColor(.gray) + } + .padding(.vertical, 4) + } + } - Text("ID: 12345678") - .font(.subheadline) - .foregroundColor(.secondary) + Section(header: Text("最近活动")) { + ForEach(6...10, id: \.self) { item in + HStack { + Image(systemName: "clock") + .foregroundColor(.orange) + .frame(width: 40, height: 40) + .background(Color.orange.opacity(0.1)) + .cornerRadius(8) + + VStack(alignment: .leading, spacing: 4) { + Text("活动 \(item)") + .font(.headline) + Text("\(item)分钟前更新") + .font(.subheadline) + .foregroundColor(.secondary) + } + + Spacer() + + Text("查看") + .font(.caption) + .padding(6) + .background(Color.blue.opacity(0.1)) + .foregroundColor(.blue) + .cornerRadius(4) + } + .padding(.vertical, 4) + } + } } + .listStyle(GroupedListStyle()) + .padding(.top, 0) - Spacer() } - .padding(.horizontal, 16) - .padding(.top, 16) - - VStack(alignment: .leading, spacing: 8) { - Text("会员等级") - .font(.headline) - .foregroundColor(.primary) - Text("会员时间") - .font(.subheadline) - .foregroundColor(.secondary) - Text("会员中心") - .font(.subheadline) - .foregroundColor(.secondary) - } - .frame(maxWidth: .infinity, alignment: .leading) - .padding(16) - .background(Color(red: 0.92, green: 0.92, blue: 0.92)) - .cornerRadius(10) - .padding(.horizontal, 16) - - VStack(spacing: 12) { - // memories - Button(action: { - print("memories") - }) { - HStack(spacing: 16) { - Image(systemName: "crown.fill") - .foregroundColor(.orange) - .frame(width: 24, height: 24) - - Text("My Memories") - .font(.headline) - .foregroundColor(.primary) - - Spacer() - } - .padding() - .cornerRadius(10) - .contentShape(Rectangle()) // 使整个区域可点击 - } - .buttonStyle(PlainButtonStyle()) // 移除按钮默认样式 - - // Box - Button(action: { - print("Box") - }) { - HStack(spacing: 16) { - Image(systemName: "clock.fill") - .foregroundColor(.blue) - .frame(width: 24, height: 24) - Text("My Bind Box") - .font(.headline) - .foregroundColor(.primary) - - Spacer() - } - .padding() - .cornerRadius(10) - .contentShape(Rectangle()) // 使整个区域可点击 - } - .buttonStyle(PlainButtonStyle()) // 移除按钮默认样式 - - // setting - Button(action: { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - showSettings = true - } - }) { - HStack(spacing: 16) { - Image(systemName: "person.circle.fill") - .foregroundColor(.purple) - .frame(width: 24, height: 24) - Text("Setting") - .font(.headline) - .foregroundColor(.primary) - Spacer() - Image(systemName: "chevron.right") - .foregroundColor(.gray) - } - .padding() - .background(Color(.systemBackground)) - .cornerRadius(10) - .contentShape(Rectangle()) // 使整个区域可点击 - } - .buttonStyle(PlainButtonStyle()) // 移除按钮默认样式 - } - .padding(.horizontal, 16) - // 这里可以添加其他设置项 - Spacer() - } - .padding(.vertical, 8) - } - - // Apply offset to the entire modal when SettingsView is shown - .offset(x: showSettings ? UIScreen.main.bounds.width : 0) - .animation(.spring(response: 0.5, dampingFraction: 0.8), value: showSettings) - - ZStack { - // Semi-transparent overlay for settings - if showSettings { - Color.black.opacity(0.4) - .edgesIgnoringSafeArea(.all) - .onTapGesture { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - showSettings = false - } - } - .transition(.opacity) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(.systemBackground)) + // 当显示弹窗时,主内容向右偏移 + .offset(x: showModal ? UIScreen.main.bounds.width * 0.8 : 0) + // 页面内元素的动画 + .animation(.spring(response: 0.6, dampingFraction: 0.8), value: showModal) + .edgesIgnoringSafeArea(.all) } - // Full screen settings view with slide animation - if showSettings { - SettingsView(isPresented: $showSettings) - .transition(.move(edge: .leading)) - .zIndex(1) // Ensure it's above other content - .onAppear { - // Reset the navigation path when settings appear - navigationPath.removeLast(navigationPath.count) - } + // 用户资料弹窗 + SlideInModal( + isPresented: $showModal, + onDismiss: hideUserProfile + ) { + UserProfileModal( + showModal: $showModal, + showSettings: $showSettings + ) } + // 当显示设置页面时,将弹窗向右移出屏幕 + .offset(x: showSettings ? UIScreen.main.bounds.width : 0) + .animation(.spring(response: 0.6, dampingFraction: 0.8), value: showSettings) + + // 设置页面遮罩层 + ZStack { + // 半透明遮罩 + if showSettings { + Color.black.opacity(0) + .edgesIgnoringSafeArea(.all) + .onTapGesture(perform: hideSettings) + .transition(.opacity) + } + + // 设置页面 + if showSettings { + SettingsView(isPresented: $showSettings) + .transition(.move(edge: .leading)) // 从左侧滑入 + .zIndex(1) // 确保设置页面在其他内容之上 + .onAppear(perform: resetNavigationPath) + } + } + .animation(.spring(response: 0.6, dampingFraction: 0.8), value: showSettings) } - .animation(.spring(response: 0.5, dampingFraction: 0.8), value: showSettings) - } - } - } -} + } + } + + // MARK: - 私有方法 + + /// 显示用户资料弹窗 + private func showUserProfile() { + withAnimation(.spring(response: 0.6, dampingFraction: 0.8)) { + showModal.toggle() + } + } + + /// 隐藏用户资料弹窗 + private func hideUserProfile() { + withAnimation(.spring(response: 0.6, dampingFraction: 0.8)) { + showModal = false + } + } + + /// 隐藏设置页面 + private func hideSettings() { + withAnimation(.spring(response: 0.6, dampingFraction: 0.8)) { + showSettings = false + } + } + + /// 重置导航路径 + private func resetNavigationPath() { + navigationPath.removeLast(navigationPath.count) + } +} + +// MARK: - 预览 #Preview { ContentView() } diff --git a/wake/Extensions/ViewExtensions.swift b/wake/Extensions/ViewExtensions.swift new file mode 100644 index 0000000..668b510 --- /dev/null +++ b/wake/Extensions/ViewExtensions.swift @@ -0,0 +1,22 @@ +import SwiftUI + +// MARK: - 圆角扩展 +struct RoundedCorner: Shape { + var radius: CGFloat = .infinity + var corners: UIRectCorner = .allCorners + + func path(in rect: CGRect) -> Path { + let path = UIBezierPath( + roundedRect: rect, + byRoundingCorners: corners, + cornerRadii: CGSize(width: radius, height: radius) + ) + return Path(path.cgPath) + } +} + +extension View { + func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View { + clipShape(RoundedCorner(radius: radius, corners: corners)) + } +} diff --git a/wake/View/Components/SheetModal.swift b/wake/View/Components/SheetModal.swift index a2bcdde..d464001 100644 --- a/wake/View/Components/SheetModal.swift +++ b/wake/View/Components/SheetModal.swift @@ -16,8 +16,8 @@ struct SlideInModal: View { ZStack(alignment: .leading) { // 遮罩背景 if isPresented { - Color.black - .opacity(0.5) + Color.clear + .contentShape(Rectangle()) .edgesIgnoringSafeArea(.all) .transition(.opacity) .zIndex(1) @@ -49,7 +49,7 @@ struct SlideInModal: View { .animation(animation, value: isPresented) } } - .frame(maxWidth: .infinity, maxHeight: .infinity) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) .edgesIgnoringSafeArea(.all) } } \ No newline at end of file diff --git a/wake/View/Components/UserProfileModal.swift b/wake/View/Components/UserProfileModal.swift new file mode 100644 index 0000000..d9f4fc5 --- /dev/null +++ b/wake/View/Components/UserProfileModal.swift @@ -0,0 +1,135 @@ +import SwiftUI + +struct UserProfileModal: View { + @Binding var showModal: Bool + @Binding var showSettings: Bool + + var body: some View { + // Modal content with transparent background + VStack(spacing: 20) { + Spacer() + .frame(height: UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0) + // 用户信息区域 + HStack(alignment: .center, spacing: 16) { + // 头像 + Image(systemName: "person.circle.fill") + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 60, height: 60) + .foregroundColor(.blue) + .clipShape(Circle()) + + // 姓名和ID + VStack(alignment: .leading, spacing: 4) { + Text("用户名") + .font(.headline) + .foregroundColor(.primary) + + Text("ID: 12345678") + .font(.subheadline) + .foregroundColor(.secondary) + } + + Spacer() + } + .padding(.horizontal, 16) + .padding(.top, 16) + + VStack(alignment: .leading, spacing: 8) { + Text("会员等级") + .font(.headline) + .foregroundColor(.primary) + Text("会员时间") + .font(.subheadline) + .foregroundColor(.secondary) + Text("会员中心") + .font(.subheadline) + .foregroundColor(.secondary) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(16) + .background(Color.clear) + .padding(.horizontal, 16) + + VStack(spacing: 12) { + // memories + Button(action: { + print("memories") + }) { + HStack(spacing: 16) { + Image(systemName: "crown.fill") + .foregroundColor(.orange) + .frame(width: 24, height: 24) + + Text("My Memories") + .font(.headline) + .foregroundColor(.primary) + + Spacer() + } + .padding() + .cornerRadius(10) + .contentShape(Rectangle()) // 使整个区域可点击 + } + .buttonStyle(PlainButtonStyle()) // 移除按钮默认样式 + + // Box + Button(action: { + print("Box") + }) { + HStack(spacing: 16) { + Image(systemName: "clock.fill") + .foregroundColor(.blue) + .frame(width: 24, height: 24) + Text("My Bind Box") + .font(.headline) + .foregroundColor(.primary) + + Spacer() + } + .padding() + .cornerRadius(10) + .contentShape(Rectangle()) // 使整个区域可点击 + } + .buttonStyle(PlainButtonStyle()) // 移除按钮默认样式 + + // setting + Button(action: { + withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { + showSettings = true + } + }) { + HStack(spacing: 16) { + Image(systemName: "person.circle.fill") + .foregroundColor(.purple) + .frame(width: 24, height: 24) + Text("Setting") + .font(.headline) + .foregroundColor(.primary) + Spacer() + Image(systemName: "chevron.right") + .foregroundColor(.gray) + } + .padding() + .background(Color.clear) + .overlay( + RoundedRectangle(cornerRadius: 10) + .stroke(Color.gray.opacity(0.2), lineWidth: 1) + ) + .contentShape(Rectangle()) // 使整个区域可点击 + } + .buttonStyle(PlainButtonStyle()) // 移除按钮默认样式 + } + .padding(.horizontal, 16) + Spacer() + } + .frame(width: UIScreen.main.bounds.width * 0.8) + .background(Color(red: 0.87, green: 0.87, blue: 0.87)) + .cornerRadius(20, corners: [.topRight, .bottomRight]) + .edgesIgnoringSafeArea(.all) + } +} + +#Preview { + UserProfileModal(showModal: .constant(true), showSettings: .constant(false)) +} diff --git a/wake/View/Owner/SettingsView.swift b/wake/View/Owner/SettingsView.swift index d49e3ef..5446eb8 100644 --- a/wake/View/Owner/SettingsView.swift +++ b/wake/View/Owner/SettingsView.swift @@ -1,153 +1,33 @@ import SwiftUI +/// 设置页面视图 struct SettingsView: View { + // MARK: - 属性 + + /// 环境变量 - 用于dismiss视图 @Environment(\.dismiss) private var dismiss - @State private var isAppeared = false + + /// 状态 - 控制视图显示/隐藏 @Binding var isPresented: Bool - // Animation configuration + // MARK: - 动画配置 + + /// 动画配置 private let animation = Animation.spring( - response: 0.8, - dampingFraction: 0.6, - blendDuration: 0.8 + response: 0.6, // 响应时间 + dampingFraction: 0.9, // 阻尼系数 + blendDuration: 0.8 // 混合时间 ) + // MARK: - 主体视图 + var body: some View { VStack(spacing: 0) { - // Custom navigation bar + // 自定义导航栏 HStack { + // 返回按钮 Button(action: { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - isPresented = false - } - }) { - HStack(spacing: 4) { - Image(systemName: "chevron.left") - .font(.system(size: 17, weight: .semibold)) - Text("Back") - } - .foregroundColor(.blue) - .padding() - } - Spacer() - Text("Settings") - .font(.headline) - .padding() - Spacer() - // Invisible view to balance the layout - Color.clear - .frame(width: 44, height: 44) - } - .background(Color(.systemBackground)) - - // Settings content - List(0..<1) { _ in - // This empty section ensures proper spacing - Section { - EmptyView() - } header: { - EmptyView() - } - // Add an invisible section header to remove extra top padding - Section(header: EmptyView()) { - EmptyView() - } - // Account & Security - HStack { - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - Image(systemName: "person.crop.circle") - .font(.system(size: 24)) - .foregroundColor(.gray) - Text("Account & Security") - Spacer() - Image(systemName: "chevron.right") - .foregroundColor(.gray) - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - } - .listRowBackground(Color(.systemBackground)) - - // Permission Management - HStack { - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - Image(systemName: "lock.shield") - .font(.system(size: 24)) - .foregroundColor(.gray) - Text("Permission Management") - Spacer() - Image(systemName: "chevron.right") - .foregroundColor(.gray) - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - } - .listRowBackground(Color(.systemBackground)) - - // Support & Service - HStack { - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - Image(systemName: "questionmark.circle") - .font(.system(size: 24)) - .foregroundColor(.gray) - Text("Support & Service") - Spacer() - Image(systemName: "chevron.right") - .foregroundColor(.gray) - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - } - .listRowBackground(Color(.systemBackground)) - - // About Us - HStack { - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - Image(systemName: "info.circle") - .font(.system(size: 24)) - .foregroundColor(.gray) - Text("About Us") - Spacer() - Image(systemName: "chevron.right") - .foregroundColor(.gray) - Color.clear - .frame(width: 12, height: 24) - .background(Color(.systemBackground)) - } - .listRowBackground(Color(.systemBackground)) - } - .listStyle(GroupedListStyle()) - .navigationTitle("Setting") - .navigationBarTitleDisplayMode(.inline) - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color(.systemGray6)) - .environment(\.horizontalSizeClass, .regular) - .environment(\.defaultMinListRowHeight, 50) - .listRowInsets(EdgeInsets()) - .onAppear { - // Remove extra separators below the list - UITableView.appearance().tableFooterView = UIView() - // Remove separator inset - UITableView.appearance().separatorInset = .zero - // Remove extra space at the top of the table view - UITableView.appearance().contentInset = .zero - } - .toolbar { - ToolbarItem(placement: .navigationBarLeading) { - Button(action: { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - isAppeared = false - } - // Delay the dismiss to allow the animation to complete - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + withAnimation(animation) { isPresented = false } }) { @@ -155,47 +35,121 @@ struct SettingsView: View { Image(systemName: "chevron.left") .font(.system(size: 16, weight: .medium)) .foregroundColor(.blue) - Text("Back") + Text("返回") .font(.system(size: 17, weight: .regular)) .foregroundColor(.blue) } } + + Spacer() + + // 标题 + Text("设置") + .font(.headline) + + Spacer() + + // 用于平衡布局的透明视图 + Color.clear + .frame(width: 44, height: 44) } + .padding(.horizontal) + .padding(.vertical, 8) + .background(Color(.systemBackground)) + + // 设置项列表 + List { + // 空Section用于调整间距 + Section { EmptyView() } + + // 账号与安全 + settingRow( + icon: "person.crop.circle", + title: "账号与安全", + action: {} + ) + + // 权限管理 + settingRow( + icon: "lock.shield", + title: "权限管理", + action: {} + ) + + // 支持与服务 + settingRow( + icon: "questionmark.circle", + title: "支持与服务", + action: {} + ) + + // 关于我们 + settingRow( + icon: "info.circle", + title: "关于我们", + action: {} + ) + } + .listStyle(GroupedListStyle()) + .listRowInsets(EdgeInsets()) } - .animation(animation, value: isAppeared) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color(.systemBackground)) + .environment(\.horizontalSizeClass, .regular) + .environment(\.defaultMinListRowHeight, 50) + .onAppear(perform: configureTableView) } -} + // MARK: - 私有方法 + + /// 配置TableView外观 + private func configureTableView() { + // 移除列表底部分隔线 + UITableView.appearance().tableFooterView = UIView() + // 移除分隔线缩进 + UITableView.appearance().separatorInset = .zero + // 移除列表顶部额外间距 + UITableView.appearance().contentInset = .zero + } + + /// 创建设置项行视图 + /// - Parameters: + /// - icon: 图标名称 + /// - title: 标题 + /// - action: 点击动作 + /// - Returns: 返回设置项行视图 + private func settingRow(icon: String, title: String, action: @escaping () -> Void) -> some View { + Button(action: action) { + HStack { + // 左侧图标 + Image(systemName: icon) + .font(.system(size: 24)) + .foregroundColor(.gray) + .frame(width: 40) + + // 标题 + Text(title) + .foregroundColor(.primary) + + Spacer() + + // 右侧箭头 + Image(systemName: "chevron.right") + .font(.system(size: 14)) + .foregroundColor(.gray) + } + .padding(.vertical, 12) + .padding(.horizontal, 16) + .background(Color(.systemBackground)) + } + .buttonStyle(PlainButtonStyle()) + .listRowBackground(Color(.systemBackground)) + } } -// MARK: - Preview +// MARK: - 预览 #Preview { NavigationView { SettingsView(isPresented: .constant(true)) } } - -// MARK: - Subviews -struct AccountSecurityView: View { - var body: some View { - Text("Account & Security") - } -} - -struct PermissionManagementView: View { - var body: some View { - Text("Permission Management") - } -} - -struct SupportServiceView: View { - var body: some View { - Text("Support & Service") - } -} - -struct AboutUsView: View { - var body: some View { - Text("About Us") - } -}