Bring Widgets to Life

You can now create interactions with widgets.  You can have animation in widgets to show how content has changed.

Animations

  • By default there is default animation by the system whenever things change
  • In regulator objects you use State, but widgets use timelines not state
  • By default this will be a spring transition, but you can use any you which from SwiftUI out of the box.. you can learn more Explore SwiftUI Animation
  • The new preview API will let you work thru this by showing you the timeline.
    • You can use #Preview(as: WidgetFamily.systemSmall) { } timeline: { entries, … }
    • For text you can use .contentTransition for important numeric values
    • Use .id(value) so that it knows when to create a new view
  • Use containerBackground to show up on all platforms.

Interactivity

  • Now you can execute actions from the widget, since widgets are stateless, via a Widget extension discovered by the system, it runs independently from your app. It takes the entries from the timeline, and is used to create a series of views to show at the appropriate time.  Your view code only runs during archiving, you can force an update by using .reloadTimelines whenever data changes in your app.  Updates to widgets are done as best effort, but reloads are guaranteed  to run.
  • You can use Buttons and Toggles to do interactivity. So you need to represent actions that can be done by App Intents.  Just like you did with ShortCuts or Siri.
  • Check out “Dive into App Intents” and “Explore enhancements to App Intents”
  • When you import SwiftUI and App Intents will provide Button and Toggle support to Widgets
  • Note that Perform in AppIntent is an async function. Make sure you persist all info needed to reload your widget.
  • Note the appIntent will also become available in Siri and ShortCuts
  • Note you can build a widget directly and Xcode will install directly on the Home Screen for you.
  • Updated widgets can cause a small latency if you use it on macOS, you can add .invalidatableContent() modifier to fix this latency.  Don’t over use this feature.
  • Toggle with update state optimistically by pre-rendering on both sides