Convert iCloud settings to macOS-native helpers

Add FixedIconWidthLabelStyle so sync category labels align when icons
have varying glyph widths.
This commit is contained in:
Arkadiusz Fal
2026-04-21 00:36:10 +02:00
parent f173dd1c39
commit 72778870e1
2 changed files with 24 additions and 16 deletions

View File

@@ -134,6 +134,21 @@ struct SettingsFormSection<Content: View>: View {
#endif #endif
} }
/// A label style that forces the icon to a fixed width so adjacent
/// labels align regardless of icon glyph width. Use when a section has
/// a vertical stack of `Label`s with mixed-width SF Symbols.
struct FixedIconWidthLabelStyle: LabelStyle {
var iconWidth: CGFloat = 22
func makeBody(configuration: Configuration) -> some View {
HStack(spacing: 8) {
configuration.icon
.frame(width: iconWidth, alignment: .center)
configuration.title
}
}
}
/// A settings row that pushes a destination view onto the navigation stack. /// A settings row that pushes a destination view onto the navigation stack.
/// ///
/// On macOS it renders as a plain full-width list row with a trailing /// On macOS it renders as a plain full-width list row with a trailing

View File

@@ -49,18 +49,16 @@ struct iCloudSettingsView: View {
} }
var body: some View { var body: some View {
List { SettingsFormContainer {
#if DEBUG #if DEBUG
Section { SettingsFormSection(footer: "settings.icloud.dev.footer") {
Label(String(localized: "settings.icloud.dev.title"), systemImage: "hammer.fill") Label(String(localized: "settings.icloud.dev.title"), systemImage: "hammer.fill")
.foregroundStyle(.orange) .foregroundStyle(.orange)
.font(.subheadline) .font(.subheadline)
} footer: {
Text(String(localized: "settings.icloud.dev.footer"))
} }
#endif #endif
Section { SettingsFormSection(footer: "settings.icloud.footer") {
Toggle(isOn: Binding( Toggle(isOn: Binding(
get: { settingsManager?.iCloudSyncEnabled ?? false }, get: { settingsManager?.iCloudSyncEnabled ?? false },
set: { newValue in set: { newValue in
@@ -73,8 +71,6 @@ struct iCloudSettingsView: View {
)) { )) {
Label(String(localized: "settings.icloud.enable"), systemImage: "icloud") Label(String(localized: "settings.icloud.enable"), systemImage: "icloud")
} }
} footer: {
Text(String(localized: "settings.icloud.footer"))
} }
if settingsManager?.iCloudSyncEnabled == true { if settingsManager?.iCloudSyncEnabled == true {
@@ -167,7 +163,7 @@ struct iCloudSettingsView: View {
@ViewBuilder @ViewBuilder
private var syncCategoriesSection: some View { private var syncCategoriesSection: some View {
Section { SettingsFormSection(footer: "settings.icloud.categories.footer") {
Toggle(isOn: Binding( Toggle(isOn: Binding(
get: { settingsManager?.syncInstances ?? true }, get: { settingsManager?.syncInstances ?? true },
set: { newValue in set: { newValue in
@@ -271,16 +267,18 @@ struct iCloudSettingsView: View {
)) { )) {
Label(String(localized: "settings.icloud.category.mediaSources"), systemImage: "externaldrive.connected.to.line.below") Label(String(localized: "settings.icloud.category.mediaSources"), systemImage: "externaldrive.connected.to.line.below")
} }
} footer: {
Text(String(localized: "settings.icloud.categories.footer"))
} }
#if os(macOS)
.labelStyle(FixedIconWidthLabelStyle())
#endif
} }
// MARK: - Sync Status Section // MARK: - Sync Status Section
@ViewBuilder @ViewBuilder
private var syncStatusSection: some View { private var syncStatusSection: some View {
Section { let footer: LocalizedStringKey? = lastManualSyncRelative.map { LocalizedStringKey("settings.icloud.lastManualSync \($0)") }
SettingsFormSection(footer: footer) {
// iCloud Account Status // iCloud Account Status
HStack { HStack {
Label(String(localized: "settings.icloud.account"), systemImage: "person.crop.circle") Label(String(localized: "settings.icloud.account"), systemImage: "person.crop.circle")
@@ -357,11 +355,6 @@ struct iCloudSettingsView: View {
Label(String(localized: "settings.icloud.syncNow"), systemImage: syncNowIcon) Label(String(localized: "settings.icloud.syncNow"), systemImage: syncNowIcon)
} }
.disabled(cloudKitSync?.isSyncing == true) .disabled(cloudKitSync?.isSyncing == true)
} footer: {
if let lastSync = lastManualSyncRelative {
Text(String(localized: "settings.icloud.lastManualSync \(lastSync)"))
}
} }
.animation(.easeInOut(duration: 0.3), value: cloudKitSync?.syncStatus) .animation(.easeInOut(duration: 0.3), value: cloudKitSync?.syncStatus)
.animation(.easeInOut(duration: 0.3), value: cloudKitSync?.uploadProgress) .animation(.easeInOut(duration: 0.3), value: cloudKitSync?.uploadProgress)