2021 EssentialsSwiftUI & UI FrameworksApp Services
WWDC21 · 27 min · Essentials / SwiftUI & UI Frameworks / App Services
Principles of great widgets
Explore the foundations of great widgets by keeping them relevant and customizable. Learn how to keep widgets up to date with timeline entries and TimelineReloadPolicies. Discover how to adapt your widget to different presentation environments and physical location. And lastly, find out how to create customizable widgets that someone can personalize to their liking.
Watch at developer.apple.com ↗Code shown on screen · 5 snippets
Xcode Previews for Widget Views with Color Scheme Overrides
struct MyWidgetEntryView : View {
var date: Date
var body: some View {
ZStack {
Rectangle().fill(BackgroundStyle())
VStack {
Text("Hello")
}
}
}
}
struct MyWidget_Previews: PreviewProvider {
static var previews: some View {
MyWidgetEntryView(date: Date())
.previewContext(WidgetPreviewContext(family: .systemSmall))
.environment(\.colorScheme, .dark)
}
} Widget Partial Privacy Redactions - Banking Example
struct MyWidgetEntryView : View {
var body: some View {
ZStack {
Rectangle().fill(BackgroundStyle())
VStack(alignment: .leading) {
Text("Balance")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(Color.blue)
Text("$128.45")
.privacySensitive()
.font(.title2)
.foregroundColor(Color.gray)
}
}
}
} WidgetBundle Example
struct IndividualSymbolWidget : Widget {
var body: some WidgetConfiguration {
…
}
}
struct StocksOverviewWidget : Widget {
var body: some WidgetConfiguration {
…
}
}
@main
struct MyWidgetBundle: WidgetBundle {
var body: some Widget {
// Order of these widgets defines the order in the Widget Gallery
IndividualSymbolWidget()
StocksOverviewWidget()
}
} Static Widget Configuration Example
@main
public struct SampleWidget: Widget {
public var body: some WidgetConfiguration {
StaticConfiguration(kind: "com.sample.myStaticSampleWidgetKind",
provider: Provider()) { entry in
SampleWidgetEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
public struct Provider: TimelineProvider {
public func timeline(with context: Context,
completion: @escaping (Timeline<Entry>) -> ()) {
let entry = SimpleEntry(date: Date())
// TODO: Generate a timeline entry
completion(timeline)
}
} Intent Widget Configuration Example
@main
public struct SampleWidget: Widget {
public var body: some WidgetConfiguration {
IntentConfiguration(kind: "com.sample.myIntentSampleWidgetKind",
intent: SampleConfigurationIntent.self
provider: Provider()) { entry in
SampleWidgetEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
public struct Provider: IntentTimelineProvider {
public func timeline(for configuration: SampleConfigurationIntent, with context: Context,
completion: @escaping (Timeline<Entry>) -> ()) {
let entry = SimpleEntry(date: Date(), configuration: configuration)
// generate a timeline
completion(timeline)
}
} Resources
Related sessions
-
18 min -
20 min -
40 min -
23 min -
20 min -
16 min -
28 min