Files
workouts/Workouts Watch Widget/WorkoutsWatchWidget.swift
rzen ce69aec988 Tint the complication glyph with the watch face color
Mark the dumbbell .widgetAccentable() so the watch face paints it with
its main accent color instead of leaving it white.
2026-06-21 09:16:55 -04:00

93 lines
3.0 KiB
Swift

import SwiftUI
import WidgetKit
// A launcher complication: a static button on the watch face that opens the
// Workouts app. It carries no data, so the timeline is a single entry that
// never refreshes. Tapping any accessory widget launches its containing app,
// so no deep link or App Group is needed.
private struct LauncherEntry: TimelineEntry {
let date: Date
}
private struct LauncherProvider: TimelineProvider {
func placeholder(in context: Context) -> LauncherEntry {
LauncherEntry(date: .now)
}
func getSnapshot(in context: Context, completion: @escaping (LauncherEntry) -> Void) {
completion(LauncherEntry(date: .now))
}
func getTimeline(in context: Context, completion: @escaping (Timeline<LauncherEntry>) -> Void) {
// Nothing ever changes one entry, never reload.
completion(Timeline(entries: [LauncherEntry(date: .now)], policy: .never))
}
}
private struct LauncherView: View {
@Environment(\.widgetFamily) private var family
private let glyph = "dumbbell.fill"
// The app icon's dumbbell runs lower-left to upper-right; tilt the glyph
// counter-clockwise to match (SwiftUI rotates clockwise for positive angles).
// `.widgetAccentable()` puts it in the accent group so the watch face tints
// it with its main color instead of leaving it white.
private var dumbbell: some View {
Image(systemName: glyph)
.rotationEffect(.degrees(-35))
.widgetAccentable()
}
var body: some View {
switch family {
case .accessoryInline:
// Inline templates render the symbol upright next to text; leave as-is.
Label("Workouts", systemImage: glyph)
case .accessoryRectangular:
HStack(spacing: 6) {
dumbbell.font(.title3)
Text("Workouts").font(.headline)
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
case .accessoryCorner:
dumbbell
.font(.title2)
.widgetLabel("Workouts")
default: // .accessoryCircular and any future families
ZStack {
AccessoryWidgetBackground()
dumbbell
.font(.title3)
}
}
}
}
struct WorkoutsLauncherComplication: Widget {
private let kind = "WorkoutsLauncher"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: LauncherProvider()) { _ in
LauncherView()
.containerBackground(.clear, for: .widget)
}
.configurationDisplayName("Open Workouts")
.description("Tap to open the Workouts app.")
.supportedFamilies([
.accessoryCircular,
.accessoryCorner,
.accessoryInline,
.accessoryRectangular,
])
}
}
@main
struct WorkoutsWatchWidgetBundle: WidgetBundle {
var body: some Widget {
WorkoutsLauncherComplication()
}
}