2022 SwiftUI & UI FrameworksApp Services
WWDC22 · 11 min · SwiftUI & UI Frameworks / App Services
Go further with Complications in WidgetKit
Discover how you can use WidgetKit to create beautiful complications on watch faces. We’ll introduce you to the watchOS-specific features found in WidgetKit, and help you migrate from existing ClockKit complications. For more on WidgetKit, watch “Complications and Widgets: Reloaded” from WWDC22.
Watch at developer.apple.com ↗Code shown on screen · 9 snippets
Large Corner
struct CornerView: View {
let value: Double
var body: some View {
ZStack {
AccessoryWidgetBackground()
Image(systemName: "cup.and.saucer.fill")
.font(.title.bold())
.widgetAccentable()
}
}
} Corner with Gauge
struct CornerView: View {
let value: Double
var body: some View {
ZStack {
AccessoryWidgetBackground()
Image(systemName: "cup.and.saucer.fill")
.font(.title.bold())
.widgetAccentable()
}
.widgetLabel {
Gauge(value: value,
in: 0...500) {
Text("MG")
} currentValueLabel: {
Text("\(Int(value))")
} minimumValueLabel: {
Text("0")
} maximumValueLabel: {
Text("500")
}
}
}
} Circular Gauge
struct CircularView: View {
let value: Double
var body: some View {
Gauge(value: value,
in: 0...500) {
Text("MG")
} currentValueLabel: {
Text("\(Int(value))")
}
.gaugeStyle(.circular)
}
} Circular Gauge with Widget Label
struct CircularView: View {
let value: Double
var body: some View {
let mg = value.inMG()
Gauge(value: value,
in: 0...500) {
Text("MG")
} currentValueLabel: {
Text("\(Int(value))")
}
.gaugeStyle(.circular)
.widgetLabel {
Text("\(mg, formatter: mgFormatter) Caffeine")
}
}
var mgFormatter: Formatter {
let formatter = MeasurementFormatter()
formatter.unitOptions = [.providedUnit]
return formatter
}
}
extension Double {
func inMG() -> Measurement<UnitMass> {
Measurement<UnitMass>(value: self, unit: .milligrams)
}
} Circular Stack with Widget Label
struct CircularView: View {
let value: Double
var body: some View {
let mg = value.inMG()
ZStack {
AccessoryWidgetBackground()
Image(systemName: "cup.and.saucer.fill")
.font(.title.bold())
.widgetAccentable()
}
.widgetLabel {
Text("\(mg, formatter: mgFormatter) Caffeine")
}
}
var mgFormatter: Formatter {
let formatter = MeasurementFormatter()
formatter.unitOptions = [.providedUnit]
return formatter
}
}
extension Double {
func inMG() -> Measurement<UnitMass> {
Measurement<UnitMass>(value: self, unit: .milligrams)
}
} Circular Stack or Gauge
struct CircularView: View {
let value: Double
(\.showsWidgetLabel) var showsWidgetLabel
var body: some View {
let mg = value.inMG()
if showsWidgetLabel {
ZStack {
AccessoryWidgetBackground()
Image(systemName: "cup.and.saucer.fill")
.font(.title.bold())
.widgetAccentable()
}
.widgetLabel {
Text("\(mg, formatter: mgFormatter) Caffeine")
}
}
else {
Gauge(value: value,
in: 0...500) {
Text("MG")
} currentValueLabel: {
Text("\(Int(value))")
}
.gaugeStyle(.circular)
}
}
var mgFormatter: Formatter {
let formatter = MeasurementFormatter()
formatter.unitOptions = [.providedUnit]
return formatter
}
}
extension Double {
func inMG() -> Measurement<UnitMass> {
Measurement<UnitMass>(value: self, unit: .milligrams)
}
} Widget Migrator
var widgetMigrator: CLKComplicationWidgetMigrator {
self
} Static Migration Configuration
func widgetConfiguration(from complicationDescriptor: CLKComplicationDescriptor) async -> CLKComplicationWidgetMigrationConfiguration? {
CLKComplicationStaticWidgetMigrationConfiguration(kind: "CoffeeTracker", extensionBundleIdentifier: widgetBundle)
} Intent Migration Configuration
func widgetConfiguration(from complicationDescriptor: CLKComplicationDescriptor) async -> CLKComplicationWidgetMigrationConfiguration? {
CLKComplicationIntentWidgetMigrationConfiguration(kind: "CoffeeTracker", extensionBundleIdentifier: widgetBundle, intent: intent, localizedDisplayName: "Coffee Tracker")
} Resources
Related sessions
-
18 min -
1 min -
23 min -
23 min