名称: swift-settingskit 描述: 适用于 SwiftUI 设置界面的 SettingsKit(iOS, macOS, watchOS, tvOS, visionOS)。用于设置/偏好屏幕、可搜索设置、嵌套导航、@Observable/@Bindable 状态,或遇到设置更新错误、导航状态问题。
关键词: SettingsKit, SwiftUI 设置, 设置界面, 偏好 UI, 可搜索设置, 设置导航, SettingsContainer, SettingsGroup, SettingsItem, CustomSettingsGroup, 设置标签, 设置搜索, Observable 设置, Bindable 设置, iOS 17, macOS 14, Swift 6, 设置样式, 侧边栏设置, 声明式设置, 设置层次结构 许可证: MIT
Swift SettingsKit
状态: 生产就绪 ✅ 最后更新: 2025-11-23 依赖: 无(独立的 Swift 包) 最新版本: SettingsKit 1.0.0+
支持的工具链
最低要求:
- Swift: 6.0+(需要 @Observable 宏和 SettingsKit 编译)
- Xcode: 16.0+(提供 Swift 6.0 工具链)
- 平台: iOS 17.0+ / macOS 14.0+ / watchOS 10.0+ / tvOS 17.0+ / visionOS 1.0+
注意: 虽然 @Observable 在 Swift 5.9 中引入,但 SettingsKit 的 Package.swift 指定 Swift 6.0+ 作为最低工具链版本。本技能中的所有示例都针对 Swift 6.0+。
快速开始(5 分钟)
1. 添加 SettingsKit 包
通过 Xcode 将 Swift 包添加到您的项目:
// 文件 → 添加包依赖
// 输入: https://github.com/aeastr/SettingsKit.git
// 版本: 1.0.0 或更高
或通过 Package.swift:
dependencies: [
.package(url: "https://github.com/aeastr/SettingsKit.git", from: "1.0.0")
]
为什么重要:
- SettingsKit 需要 iOS 17+ / macOS 14+ 以支持现代 SwiftUI 功能
- Swift 6.0+ 需要支持 @Observable 宏
- 框架在所有苹果平台上自适应
2. 创建 Observable 设置模型
import SwiftUI
import SettingsKit
@Observable
class AppSettings {
var notificationsEnabled = true
var darkMode = false
var username = "Guest"
var fontSize: Double = 14.0
}
关键:
- 使用
@Observable宏(而不是@Published或ObservableObject) - SettingsKit 设计用于 Swift 的现代观察系统
- 设置模型必须在 SwiftUI 环境中以进行绑定
3. 实现 SettingsContainer 协议
struct MySettings: SettingsContainer {
@Environment(AppSettings.self) var appSettings
var settingsBody: some SettingsContent {
@Bindable var settings = appSettings
SettingsGroup("General", systemImage: "gear") {
SettingsItem("Notifications") {
Toggle("Enable", isOn: $settings.notificationsEnabled)
}
SettingsItem("Dark Mode") {
Toggle("Enable", isOn: $settings.darkMode)
}
}
SettingsGroup("Profile", systemImage: "person") {
SettingsItem("Username") {
TextField("Username", text: $settings.username)
}
SettingsItem("Font Size") {
Slider(value: $settings.fontSize, in: 10...24)
Text("\(Int(settings.fontSize))pt")
}
}
}
}
关键:
- 必须使用
@Bindable包装器从 @Observable 模型创建绑定 settingsBody返回SettingsContent(而不是View)- 组在侧边栏样式中显示为导航链接(可点击的行)
4. 添加到您的应用
import SwiftUI
import SettingsKit
@main
struct MyApp: App {
@State private var settings = AppSettings()
var body: some Scene {
WindowGroup {
MySettings()
.environment(settings)
}
}
}
结果: 完整的设置界面,包括:
- 自动导航(iPad/Mac 上的侧边栏,iPhone 上的单列)
- 内置搜索功能
- 平台自适应呈现
- 响应式状态更新
四步设置过程
步骤 1: 安装包依赖
通过 Xcode 中的 Swift 包管理器添加 SettingsKit:
- 文件 → 添加包依赖
- 输入仓库 URL:
https://github.com/aeastr/SettingsKit.git - 选择“从 1.0.0 起的最新主要版本”
- 添加到您的应用目标
关键点:
- 需要 Xcode 16.0+ 以支持 Swift 6.0
- 包包含所有平台(iOS、macOS、watchOS、tvOS、visionOS)
- 无需额外配置
步骤 2: 定义设置数据模型
创建一个 @Observable 类来保存您的设置状态:
import SwiftUI
@Observable
class AppSettings {
// 通用设置
var notificationsEnabled = true
var soundEnabled = true
var hapticFeedback = true
// 外观设置
var darkMode = false
var accentColor: Color = .blue
var fontSize: Double = 16.0
// 用户资料
var username = ""
var email = ""
var profileImageURL: URL?
}
关键点:
- 使用
@Observable宏(Swift 6.0+)进行现代观察 - 初始化所有属性为默认值
- 保持设置模型与视图逻辑分离
- 可以包含计算属性以派生状态
步骤 3: 构建设置层次结构
实现 SettingsContainer 协议来定义您的设置 UI:
import SettingsKit
struct MySettings: SettingsContainer {
@Environment(AppSettings.self) var appSettings
var settingsBody: some SettingsContent {
@Bindable var settings = appSettings
// 导航组(可点击的行)
SettingsGroup("General", systemImage: "gear") {
SettingsItem("Notifications") {
Toggle("Enable", isOn: $settings.notificationsEnabled)
}
SettingsItem("Sound Effects") {
Toggle("Enable", isOn: $settings.soundEnabled)
}
}
.settingsTags(["notifications", "sounds", "alerts"])
// 内联组(节标题)
SettingsGroup("Quick Settings", .inline) {
SettingsItem("Dark Mode") {
Toggle("Enable", isOn: $settings.darkMode)
}
}
// 嵌套导航
SettingsGroup("Profile", systemImage: "person") {
SettingsGroup("Account", systemImage: "person.circle") {
SettingsItem("Username") {
TextField("Username", text: $settings.username)
}
SettingsItem("Email") {
TextField("Email", text: $settings.email)
}
}
}
}
}
关键点:
SettingsGroup创建导航链接(默认)或节标题(.inline)SettingsItem包装单个控件- 添加
.settingsTags([...])以增强搜索可发现性 - 组可以无限嵌套以实现深层次结构
步骤 4: 配置呈现样式
选择如何显示设置:
// 侧边栏样式(默认)- iPad/Mac 上的拆分视图
MySettings(settings: settings)
.settingsStyle(.sidebar)
// 单列样式 - 所有平台上的简洁列表
MySettings(settings: settings)
.settingsStyle(.single)
// 自定义样式 - 对外观完全控制
MySettings(settings: settings)
.settingsStyle(MyCustomStyle())
关键点:
.sidebar: 使用基于选择的导航的 NavigationSplitView(默认).single: 使用推送导航的单个 NavigationStack- 自定义样式符合
SettingsStyle协议 - 平台自动适应设备上下文
关键规则
总是做
✅ 使用 @Observable 作为设置模型 - 需要 SettingsKit 的响应式系统
✅ 使用 @Bindable 包装环境设置 - 在 settingsBody 中启用双向绑定
✅ 为重要组添加可搜索标签 - 通过 .settingsTags([...]) 提高可发现性
✅ 将设置模型保持在 SwiftUI 环境中 - 在父视图中使用 .environment(settings)
✅ 对所有交互式控件使用 SettingsItem - 确保正确的搜索索引
永远不做
❌ 永远不要使用 ObservableObject 和 @Published - SettingsKit 需要现代 @Observable ❌ 永远不要在没有 @Bindable 包装器的情况下创建绑定 - 会导致编译错误 ❌ 永远不要在 settingsBody 中放置重计算 - 每次渲染都计算,保持轻量级 ❌ 永远不要忘记将设置注入环境 - 导致运行时崩溃 ❌ 永远不要对简单控件使用 CustomSettingsGroup - 不必要地绕过搜索索引
已知问题预防
本技能预防 5 个记录的问题:
问题 #1: “无法将类型 ‘Binding<T>’ 的值转换为期望的参数类型 ‘Binding<U>’”
错误: 尝试在没有 @Bindable 包装器的情况下绑定到 @Observable 属性时编译错误
来源: Swift 并发迁移指南,Observable 宏文档
发生原因: @Observable 模型需要 @Bindable 包装器来创建绑定,不像 @Published 属性
预防: 在创建绑定之前,始终在 settingsBody 中使用 @Bindable var settings = appSettings
问题 #2: 模型更改时设置 UI 未更新
错误: 切换开关、滑块和文本字段不反映模型更改
来源: SettingsKit GitHub 问题,SwiftUI 观察系统文档
发生原因: 设置模型未正确注入 SwiftUI 环境,中断观察
预防: 在父视图中使用 .environment(settings) 并在 SettingsContainer 中使用 @Environment(AppSettings.self)
问题 #3: 侧边栏样式中的导航状态冲突
错误: 选择设置项不导航,或导航堆栈损坏 来源: SettingsKit 架构文档,NavigationSplitView 最佳实践 发生原因: 在侧边栏样式中使用 NavigationLink 而不是 SettingsGroup 导致状态冲突 预防: 始终使用 SettingsGroup 进行导航(永远不要使用原始 NavigationLink),让 SettingsKit 管理导航状态
问题 #4: 自定义组未出现在搜索结果中
错误: CustomSettingsGroup 内容对搜索功能不可见 来源: SettingsKit README - “自定义组可通过标题/图标/标签搜索,但内容渲染时没有元素索引” 发生原因: CustomSettingsGroup 绕过标准索引以实现完全 UI 控制,只有元数据可搜索 预防: 对可搜索内容使用常规 SettingsGroup/SettingsItem,将 CustomSettingsGroup 保留给复杂的自定义 UI
问题 #5: 在 macOS 上设置崩溃,出现“Nil coalescing”运行时错误
错误: 在 macOS 上打开设置时应用崩溃,涉及基于目标的导航问题 来源: SettingsKit macOS 特定实现注释 发生原因: macOS 使用基于目标的 NavigationLink(而不是基于选择)以防止控制更新问题,但需要正确的导航状态设置 预防: 让 SettingsKit 处理导航堆栈创建,在 macOS 上不要将 SettingsContainer 包装在自定义 NavigationStack 中
配置文件参考
Package.swift(完整示例)
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyApp",
platforms: [
.iOS(.v17),
.macOS(.v14),
.watchOS(.v10),
.tvOS(.v17),
.visionOS(.v1)
],
products: [
.executable(name: "MyApp", targets: ["MyApp"])
],
dependencies: [
.package(url: "https://github.com/aeastr/SettingsKit.git", from: "1.0.0")
],
targets: [
.executableTarget(
name: "MyApp",
dependencies: [
.product(name: "SettingsKit", package: "SettingsKit")
]
)
]
)
为什么这些设置:
- 平台版本匹配 SettingsKit 最低要求(iOS 17+ 等)
- 需要 Swift 工具版本 6.0+ 以支持 @Observable 宏
- SettingsKit 作为包依赖添加,使用语义版本控制
常见模式
模式 1: 模块化设置组
将复杂的设置部分提取到单独的 SettingsContent 类型中,以更好地组织:
struct NotificationSettings: SettingsContent {
@Bindable var settings: AppSettings
var body: some SettingsContent {
SettingsGroup("Notifications", systemImage: "bell") {
SettingsItem("Enable Notifications") {
Toggle("Enable", isOn: $settings.notificationsEnabled)
}
if settings.notificationsEnabled {
SettingsItem("Sound") {
Toggle("Enable", isOn: $settings.soundEnabled)
}
SettingsItem("Badge") {
Toggle("Show badge", isOn: $settings.badgeEnabled)
}
}
}
.settingsTags(["notifications", "alerts", "sounds", "badges"])
}
}
// 在主设置中使用:
var settingsBody: some SettingsContent {
NotificationSettings(settings: settings)
AppearanceSettings(settings: settings)
PrivacySettings(settings: settings)
}
何时使用: 具有 5+ 组、条件内容或团队协作不同部分的复杂设置层次结构
模式 2: 可搜索的自定义开发工具
使用 CustomSettingsGroup 处理高级 UI,同时保持可搜索性:
CustomSettingsGroup("Developer Tools", systemImage: "hammer") {
VStack(spacing: 20) {
GroupBox("Debug Information") {
VStack(alignment: .leading, spacing: 8) {
Text("App Version: 1.0.0")
Text("Build: 42")
Text("Environment: Production")
}
.frame(maxWidth: .infinity, alignment: .leading)
}
Button("Clear Cache") {
clearCache()
}
.buttonStyle(.borderedProminent)
Button("Export Logs", systemImage: "square.and.arrow.up") {
exportLogs()
}
}
.padding()
}
.settingsTags(["debug", "testing", "logs", "advanced"])
何时使用: 不适合标准 SettingsItem 模式的复杂自定义 UI,但仍需要通过标签搜索可发现性
模式 3: 条件设置可见性
基于功能标志或用户权限显示/隐藏设置:
SettingsGroup("Advanced", systemImage: "gearshape.2") {
SettingsItem("Enable Advanced Features") {
Toggle("Enable", isOn: $settings.showAdvanced)
}
if settings.showAdvanced {
SettingsItem("Beta Features") {
Toggle("Enable", isOn: $settings.betaFeaturesEnabled)
}
SettingsItem("Developer Mode") {
Toggle("Enable", isOn: $settings.developerMode)
}
}
if settings.developerMode {
SettingsGroup("Developer Options", systemImage: "wrench.and.screwdriver") {
SettingsItem("Verbose Logging") {
Toggle("Enable", isOn: $settings.verboseLogging)
}
}
}
}
何时使用: 功能标志、用户权限级别、逐步披露复杂性
模式 4: 所有控件类型
SettingsItem 支持所有标准 SwiftUI 控件:
SettingsGroup("All Controls", systemImage: "slider.horizontal.3") {
// Toggle(布尔值)
SettingsItem("Enable Feature") {
Toggle("Enable", isOn: $settings.featureEnabled)
}
// Slider(连续值)
SettingsItem("Volume") {
VStack(alignment: .leading, spacing: 8) {
Slider(value: $settings.volume, in: 0...100)
Text("\(Int(settings.volume))%")
.font(.caption)
.foregroundStyle(.secondary)
}
}
// TextField(文本输入)
SettingsItem("Username") {
TextField("Enter username", text: $settings.username)
.textFieldStyle(.roundedBorder)
}
// Picker(选择)
SettingsItem("Theme") {
Picker("", selection: $settings.theme) {
Text("Light").tag(Theme.light)
Text("Dark").tag(Theme.dark)
Text("Auto").tag(Theme.auto)
}
.pickerStyle(.segmented)
}
// Stepper(递增/递减)
SettingsItem("Font Size") {
Stepper("\(Int(settings.fontSize)) pt", value: $settings.fontSize, in: 10...24)
}
// Button(动作)
SettingsItem("Reset Settings") {
Button("Reset") {
resetSettings()
}
.buttonStyle(.borderedProminent)
.tint(.red)
}
// ColorPicker(颜色选择)
SettingsItem("Accent Color") {
ColorPicker("Choose color", selection: $settings.accentColor)
}
// DatePicker(日期/时间选择)
SettingsItem("Reminder Time") {
DatePicker("", selection: $settings.reminderTime, displayedComponents: .hourAndMinute)
}
}
何时使用: 构建设置时的控件可用性参考
何时加载参考文件
为特定主题加载额外的参考文件以获得详细文档:
-
加载
references/api-reference.md当实现高级 SettingsContainer 自定义、自定义 SettingsContent 类型,或需要所有协议和修饰符的详细 API 文档时 -
加载
references/styling-guide.md当自定义设置外观、实现自定义 SettingsStyle,或需要平台特定样式指导时 -
加载
references/search-implementation.md当实现自定义搜索逻辑、调试搜索行为,或需要理解 SettingsKit 的搜索架构时 -
加载
references/advanced-patterns.md当构建复杂嵌套层次结构、实现动态设置、处理持久性,或需要生产就绪的架构模式时 -
加载
references/performance-edge-cases.md当构建大型设置层次结构(100+ 组或 1000+ 项)、遇到性能问题,或需要压力测试指导和优化策略时
使用捆绑资源
脚本(scripts/)
未包含脚本 - SettingsKit 是纯 Swift 包,无需构建脚本。
参考(references/)
高级主题的详细文档文件:
references/api-reference.md- 所有 SettingsKit 协议、类型和修饰符的完整 API 文档references/styling-guide.md- 自定义设置外观和平台特定行为的综合指南references/search-implementation.md- 搜索架构、自定义搜索实现和搜索评分的深入探讨references/advanced-patterns.md- 复杂层次结构、状态管理、持久性和测试的生产模式references/performance-edge-cases.md- 性能优化、压力测试和处理大型层次结构
何时加载: 请参见上面的“何时加载参考文件”部分,了解具体场景
资产(assets/)
用于快速设置的 Swift 模板文件:
assets/basic-settings-template.swift- 完整的最小设置实现assets/custom-style-template.swift- 自定义 SettingsStyle 实现模板(5 个示例)assets/modular-settings-template.swift- 多文件设置组织模式assets/demo-app-template.swift- 完整演示应用,匹配官方 SettingsKit 演示(25+ 属性,所有控件类型,压力测试)
依赖
必需:
- Swift 6.0+(用于 @Observable 宏支持)
- iOS 17.0+ / macOS 14.0+ / watchOS 10.0+ / tvOS 17.0+ / visionOS 1.0+
- SwiftUI 框架(内置)
可选:
- 无 - SettingsKit 是独立框架,无外部依赖
官方文档
- SettingsKit GitHub: https://github.com/Aeastr/SettingsKit
- Swift Observation: https://developer.apple.com/documentation/observation
- SwiftUI Navigation: https://developer.apple.com/documentation/swiftui/navigation
- Context7 Library ID: 不适用(尚未索引)
包版本(已验证 2025-11-23)
{
"dependencies": {
"SettingsKit": "1.0.0"
}
}
平台要求:
- iOS 17.0+
- macOS 14.0+
- watchOS 10.0+
- tvOS 17.0+
- visionOS 1.0+
- Swift 6.0+
- Xcode 16.0+
生产示例
本技能基于官方 SettingsKit 仓库和示例:
- 仓库: https://github.com/Aeastr/SettingsKit
- 许可证: MIT
- 验证: ✅ 在 iOS 17+、macOS 14+、watchOS 10+、tvOS 17+、visionOS 1+ 上测试
- 架构: 混合元数据/视图/渲染系统,用于可搜索 + 响应式设置
故障排除
问题: “找不到 ‘SettingsContainer’ 在作用域中”
解决方案: 在文件顶部导入 SettingsKit:import SettingsKit。在 Xcode 项目设置中验证包已添加到目标依赖。
问题: 模型更改时设置切换不更新
解决方案: 确保设置模型在 SwiftUI 环境中(.environment(settings)),并在创建绑定之前在 settingsBody 中使用 @Bindable 包装器。
问题: 侧边栏样式中导航不工作
解决方案: 验证使用 SettingsGroup(而不是原始 NavigationLink),并且不要将 SettingsContainer 包装在自定义 NavigationStack/NavigationSplitView 中。
问题: 搜索找不到我的自定义设置
解决方案: 向组添加 .settingsTags([...]) 和相关的关键词。CustomSettingsGroup 内容未被索引——对可搜索控件使用 SettingsItem。
完整设置检查清单
使用此检查清单验证您的设置:
- [ ] SettingsKit 包已添加(1.0.0+)通过 Swift 包管理器
- [ ] 满足最低平台版本(iOS 17+ / macOS 14+ / Swift 6.0+)
- [ ] 设置模型使用 @Observable(而不是 ObservableObject)
- [ ] SettingsContainer 协议已实现,带有 settingsBody
- [ ] 在创建绑定之前使用了 @Bindable 包装器
- [ ] 设置模型已注入环境(.environment(settings))
- [ ] 设置组使用 .settingsTags([…]) 进行搜索
- [ ] 应用编译无误
- [ ] 设置 UI 在目标平台上正确显示
- [ ] 搜索功能正常工作(尝试搜索带标签的关键词)
- [ ] 设置状态持久并响应更新
问题?问题?
- 检查
references/api-reference.md获取详细 API 文档 - 查看
references/advanced-patterns.md获取复杂场景 - 验证四步设置过程中的所有步骤
- 检查官方仓库: https://github.com/Aeastr/SettingsKit
- 确保满足 Swift 6.0+ 和 iOS 17+ / macOS 14+ 要求