Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2023-10148
$eventId
ID of event: wwdc2023
$eventContentId
ID of session without event part: 10148
$eventShortId
Shortened ID of event: wwdc23
$year
Year of session: 2023
$extension
Extension of original filename: mp4
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2023] [Session 10148] What’s ne...

WWDC23 • Session 10148

What’s new in SwiftUI

SwiftUI & UI Frameworks • iOS, macOS, tvOS, visionOS, watchOS • 34:02

Learn how you can use SwiftUI to build great apps for all Apple platforms. Explore the latest updates to SwiftUI and discover new scene types for visionOS. Simplify your data models with the latest data flow options and learn about the Inspector view. We’ll also take you through enhanced animation APIs, powerful ScrollView improvements, and a host of refinements to help you make tidier tables, improve focus and keyboard input, and so much more.

Speakers: Curt Clifton, Jeff Robertson

Open in Apple Developer site

Transcript

[Curt Clifton]

Hello and thanks for joining us. I'm Curt and I'm an engineer on the SwiftUI team.

[Jeff Robertson]

And I'm Jeff. I'm also an engineer on the SwiftUI team. We're happy to have the chance to share what's new in SwiftUI.

[Curt Clifton]

You can now use SwiftUI in even more places, including a brand-new platform! New data flow types dramatically simplify modeling your domain, providing more power than ever before. The Inspector, plus Table improvements, provide great ways to display your data. The team amped up our animation APIs, letting you create even more beautiful experiences for the people using your apps. Across the framework, we've enhanced your ability to provide great interactions, with powerful scroll view improvements, refinements to Focus and keyboard input, and deeper customization of controls like buttons and menus. I'm excited to tell you about some great new places to use SwiftUI.

From the headset and watchOS 10 to new widgets and cross-framework integration, SwiftUI can help you create experiences that delight the people who use your apps. Spatial computing brings SwiftUI into a bold new future with all-new 3D capabilities like volumes; rich experiences with immersive spaces; new 3D gestures, effects, and layout; and deep integration with RealityKit.

From core pieces like the Home View in Control Center to familiar apps like TV, Safari, and Freeform; to all-new environments like immersive rehearsals in Keynote; SwiftUI is at the heart of these user experiences. On this new platform, construct windows using familiar scene types like WindowGroup. WindowGroup scenes render as 2D windows, with delightful depth-sensitive 3D controls. Within a window, choose one of the usual SwiftUI containers, like NavigationSplitView or TabView.

Within these containers, you can use all the usual SwiftUI controls just like on the other platforms. For even more depth, apply the volumetric style to your scene. Volumes display 3D experiences -- like board games or architectural models -- in a bounded space. They display alongside other apps. People can use your content while they jot down thoughts in Notes or update slides in Keynote. Fill a volume with a static model using Model3D.

For dynamic, interactive models with lighting effects and more, use the new RealityView. To go truly all in, add ImmersiveSpaces to your app. The new ImmersiveSpace scene type lets you define immersive, spatial experiences, whether embedded in your surroundings or with full immersion. The system whisks other apps away letting people dive into the world you've created.

Use an ImmersiveSpace with the mixed immersion style to connect your app to the real world, combining your content with people's surroundings. Anchor elements of your app to tables and surfaces, and augment and enrich the real world with virtual objects and effects. Go further with the full immersion style.

Your app takes complete control. Build these connected and immersive experiences using the same Model3D and RealityView that work in volumes. SwiftUI on this new platform lets you create magical experiences. Watch "Meet SwiftUI for spatial computing" to continue exploring this great combination. SwiftUI is at home building a room-filling experience, but it can also build experiences for Apple's most portable displays.

watchOS 10 delivers a redesigned user experience that surfaces timely information, conveys focused content at a glance, and celebrates the shape and fidelity of the display. We've updated apps across the platform to take advantage of this beautiful full-screen color and imagery. At the root of these designs are several existing SwiftUI views, newly empowered for watchOS 10.

NavigationSplitView and NavigationStack get beautiful new transitions. TabView gets a new vertical paging style driven by the Digital Crown. SwiftUI introduces some new API to help you bring this full-color flair to your Apple Watch apps too. The new containerBackground modifier lets you configure these subtle background washes that animate when you push and pop content. You can also configure backgrounds for tab views on watchOS.

And new multiplatform toolbar placements -- topBarLeading and topBarTrailing, along with the existing bottomBar -- let you perfectly place these small detail views in your Apple Watch apps. Besides these new additions, we're pleased to bring some existing API to watchOS for the first time, including DatePicker and selection in Lists.

Now is a great time to polish your Apple Watch apps with these new capabilities. And if you don't have an Apple Watch app yet, it's a great time to begin. Learn how design and engineering come together to create these experiences in "Design and build apps for watchOS 10." Then apply these ideas to your work with "Update your app for watchOS 10." Widgets for the Smart Stack on watchOS 10 let the people using your app see their information on the go. SwiftUI is core to widgets wherever they appear, like these other new places. Widgets on the Lock Screen on iPadOS 17 are a great complement to widgets on the Home Screen.

Big, bold widgets shine on the iPhone Always-On display with Standby Mode. And desktop widgets on macOS Sonoma keep people up to date during their day-to-day. Widgets have found their way to new places, and the team has also taught them another trick. I'm thrilled to share that widgets now support interactive controls. Toggle and Button in Widgets can now activate code defined in your own app bundle using App Intents. And you can animate your widgets using SwiftUI transition and animation modifiers.

To get started with these great new capabilities, check out "Bring widgets to new places" and "Bring widgets to life." To develop and refine your new interactive animated widgets, you'll love the power of Xcode Previews. Previews leverage macros in Swift 5.9 to provide an elegant new syntax. Declare and configure a Preview, add a widget type, and define a timeline for testing. Xcode Previews shows the current widget state and a timeline that lets you see the animations between states. Of course, the new previews work with regular SwiftUI views and apps as well. And you can now interact with previews of Mac apps right inside Xcode.

Check out the talk "Build programmatic UI with Xcode Previews" to learn how to leverage these terrific new tools to accelerate your app and widget development. Besides the macros that power previews, Swift 5.9 also brings a host of other improvements. Get an overview of all that's fresh in Swift by queueing up "What's new in Swift." Another way SwiftUI comes to new places is through SwiftUI-specific extensions to other Apple frameworks. Several frameworks bring new or improved support, and I'd like to highlight a few that I think are particularly exciting.

MapKit delivers a massive update that gives you the power of Apple's marvelous mapping framework right in your SwiftUI code. Simply import SwiftUI and MapKit to use these great features. Put a map in your view. Add custom markers, polylines, and the user's location. Configure the available controls. To learn all about adding amazing maps to your SwiftUI app, check out the talk "Meet MapKit for SwiftUI." In its sophomore season, Swift Charts brings a slew of great improvements, including scrolling charts, built-in support for selection, and something I know folks have been hungry for: donut and pie charts with the new SectorMark.

To dig into these new features, check out the talk "Explore pie charts and interactivity in Swift Charts." For building experiences that attract and retain loyal customers, you'll love the ease and power of the new in-app purchase and subscription stores. Present a subscription store view with your custom marketing content.

Configure a full-bleed background to match your branding and choose from a variety of control options. Watch "Meet StoreKit for SwiftUI" to power up your in-app marketing game. From new platforms and widgets, to cross-framework integration and the beauty of watchOS, SwiftUI continues to push the Apple developer experience forward. It's exciting to see all the new places to use SwiftUI, Jeff.

[Jeff Robertson]

Certainly! And we also have a lot of great improvements that work across all our platforms.

[Curt Clifton]

Indeed!

[Jeff Robertson]

We should work on an app that uses these improvements.

[Curt Clifton]

Oh, agreed! Have you thought any more about my idea?

[Jeff Robertson]

The one about dogs? Curt: Yeah! It's like bird-watching but for dogs!

[Jeff Robertson]

Do you really think people want a dog-watching app?

[Curt Clifton]

Oh, certainly! The pitch deck practically writes itself.

[Jeff Robertson]

With our million-dollar idea in place, it's time to start building out our app. Since every great app begins with a great data model, let's start by looking at the pack of great new features SwiftUI has for working with our app's data. One of my favorite things about SwiftUI is how it lets me define my UI as a function of my app's state. I'm happy to share the biggest upgrade to how you define your model types with SwiftUI: the new Observable macro.

Observable models let you use familiar SwiftUI patterns for data flow, while also making your code more concise and performant. Here's the model class I've set up to store data representing dogs I've met while out and about. To make this type an Observable, I'll add the macro to my type. That's all I need to do. Unlike ObservableObject, there's no need to mark properties as Published.

Observable models easily integrate into the existing SwiftUI mechanisms for data flow. Let's use my DogCard view as an example. When using an Observable in your View, SwiftUI will automatically establish dependencies on properties you read. There's also no need to use a property wrapper when reading, so your view code is cleaner.

And this view is reading the isFavorite property, so when that changes, it will get reevaluated. Invalidation only happens for properties which are read, so you can pass your model through intermediate views without triggering any unnecessary updates. SwiftUI includes several tools for defining your state and its relationship to your views, several of which are designed for use with ObservableObject. When using Observable, this is becomes even simpler since it's designed to work directly with the State and Environment dynamic properties.

In addition to modeling read-only values, Observables are also a natural fit to represent mutable state, like on this form for a new dog sighting. The model is defined using the State dynamic property, and I'm passing bindings to its properties to the form elements responsible for editing that property.

Lastly, Observable types integrate seamlessly into the environment. Since views throughout our app want a way to fetch the current user, I've added it to the environment of my root view. The user profile view then reads the value using the Environment dynamic property. I'm using the type as the environment key here, but custom keys are also supported.

Be sure to catch "Discover Observation with SwiftUI" to learn more on how you can take advantage of this powerful new tool. I love how Observable lets me write clear and concise code. It's given me a great start to my app, but I'd really like to make sure any changes to my data model are persisted, so that I never lose track of all my favorite pups. SwiftData is an all-new framework for data modeling and management. It's fast and scalable and works great with SwiftUI.

SwiftData models are represented entirely by their code, making them a natural fit for any SwiftUI app. To set up my Dog model type for SwiftData, I'll switch from using Observable to the Model macro. This is the only change I need to make. In addition to the persistence provided by SwiftData, models also receive all the benefits of using Observable. It's really powerful. Our dog-watching app's main screen shows a scrolling stack of recently met doggos. Let's take a walk through the changes needed to use SwiftData here.

First, I'll add a model container to my app's definition and provide it my model type. Then, in my view code, I'll switch my array of dogs to use the new Query dynamic property. Using Query will tell SwiftData to fetch the model values from the underlying database. When the data changes, like when I spot a new dog, my view will be invalidated. Query is incredibly efficient for large data sets and allows for customization in how the data is returned, such as changing the sort order to use the date I spotted the dog, which makes for a better experience in the app.

SwiftData also works great for storing a document's data on macOS and iOS. I decided I wanted a quick way to prototype some dog tag visual treatments for our app, so I built this little document-based app for collaborating with Curt and our designers. Document-based apps can take advantage of all the functionality of SwiftData using a new initializer. SwiftUI will then use SwiftData for the underlying storage of each document, as well as automatically set up a model container.

To learn more about SwiftData and how it integrates with SwiftUI, please watch "Meet SwiftData" and "Build an app with SwiftData." In addition to SwiftData support, DocumentGroup also gains a number of new platform affordances when running on iOS 17 or iPadOS 17, such as automatic sharing and document renaming support, as well as undo controls in the toolbar.

Inspector is a new modifier for displaying details about the current selection or context. It's presented as a distinct section in your interface. On macOS, Inspector presents as a trailing sidebar. as well as on iPadOS in a regular size class. In compact size classes, it will present itself as a sheet.

To uncover all the details on Inspector, watch "Inspectors in SwiftUI: discover the details." Dialogs have been given several new customization APIs in iOS 17 and macOS Sonoma. I'm using some of the new modifiers to give my image export dialog some useful information, like adjusting the confirmation button's label.

An increased severity helps draw attention to important confirmation dialogs, and including a suppression toggle indicates a preference that the dialog should not present itself for subsequent interactions. Lastly, adding a HelpLink can be a guide to further information about the purpose of the dialog. Lists and tables are a key part of most apps, and SwiftUI has brought some new features and APIs for fine-tuning them in iOS 17 and macOS Sonoma.

Tables support customization of their column ordering and visibility. When coupled with the SceneStorage dynamic property, these preferences can be persisted across runs of your app. You provide the table with a value representing the customization state and give each column a unique stable identifier. Tables now also have all the power of OutlineGroup built in. This is great for large data sets that lend themselves to a hierarchical structure, like this one which groups some of my favorite dogs with their proud parents.

Simply use the new DisclosureTableRow to represent rows that contain other rows, and build the rest of your table as you would normally. Sections within a list or table have gained support for programmatic expansion. I've used it here in my app's sidebar to show the location section as collapsed initially, but while still allowing for expansion.

The new initializer takes a binding to a value which reflects the current expansion state of the section. For smaller data sets, tables have also gained a few new styling affordances, such as how row backgrounds and column headers are displayed. And lastly, custom controls like my star rating will also benefit from the new background prominence environment property.

Using a less prominent foreground style when the background is prominent lets my custom control feel right at home in a list. In addition to these and other APIs that let you fine-tune the look and feel of lists and tables, we've also made big improvements to the performance, particularly when dealing with large data sets. To learn more about this and the ways you can optimize your own SwiftUI views, check out "Demystify SwiftUI performance." From Observable to SwiftData to Inspector and table customizations, working with data in your apps feels like a whole new experience.

[Curt Clifton]

With the data model and tables that Jeff has put together, we have the bones of a great app. I'd like to add some pizazz using the extraordinary new animation APIs. I think it would be great to have an Apple TV app for viewing a gallery of dog photos. Here's an animation I've been working on for choosing the current viewer.

I built this with the new Keyframe Animator API. Keyframe animators let me animate multiple properties in parallel. I give the animator a value containing animatable properties and a piece of equatable state. Changes to the state trigger my animation. In the first closure, I build a view, modified by my animatable properties, like the vertical offset of my logo. In the second closure, I define how these properties change over time.

For example, the first track defines the animation of my verticalTranslation property. I pull my logo down 30 points over the first quarter second using a spring animation. Then I make my Beagle leap and land using a cubic curve. Finally, I bring this dog home with a natural spring animation. I define additional tracks for my other animated properties. All these tracks run in parallel to create this cool animation.

To learn how to leverage keyframe animators in your apps, check out "Wind your way through advanced animations in SwiftUI." I've also been working on an Apple Watch app to record dog sightings when I'm out on a run. It's pretty simple so far, just our happy icon and a button to register a sighting. I'd like to animate this icon when I tap the button. This is a good place for a phase animator.

A phase animator is simpler than a keyframe animator. Instead of parallel tracks, it steps through a single sequence of phases. This lets me start one animation when the previous animation finishes. I give the animator a sequence of phases and tell it to run my animation whenever my sightingCount changes.

Then in this first closure, I set the rotation and scale of my happy dog based on the current phase. The second closure tells SwiftUI how to animate into each phase. I'm using some of the cool new spring animations here. I just love these names. Who doesn't want a snappy or bouncy animation? And for my grow phase, I'm using an entirely custom spring. Springs now take a duration and bounce, making them easier to describe.

You can use all these new springs everywhere that takes a SwiftUI animation. Spring animations have a nice, natural feel. They match the velocity of any previous animation and settle to their final value with realistic friction. They're now the default animation for apps built on or after iOS 17 and aligned releases.

I'm pleased with my animation now, but when I'm out on a run, it would be great to also get some haptic feedback. Haptic feedback provides a tactile response, such as a tap, to draw attention and reinforce actions and events. I think a tap on the wrist would give me more confidence that I didn't miss a dog. Haptic feedback is easy with the new sensory feedback API. To play haptic feedback, I just attach the sensoryFeedback modifier, specify what sort of feedback I want and when it should happen.

The sensoryFeedback modifier works on all platforms that support haptic feedback. Different platforms support different kinds of feedback, so check out the Human Interface Guidelines to learn what sorts of feedback will be best in your apps. I've also been working on an animation for the welcome screen, using the new visual effects modifier. The visual effects modifier lets me update these dog photos based on their position. And I don't need a GeometryReader to do it. I've got a little simulation that moves a focal point around the screen. This red dot shows what I mean by focal point.

I associate a coordinate space with this grid that shows all the dogs. Then inside my DogCircle view, I add a visual effect. The closure gets my content to modify and a geometry proxy. I'm passing the geometry proxy to a helper method to compute the scale. I can use the geometry proxy to get the size of my grid view and the frame of a single dog circle relative to my grid view. That lets me compute how far any dog is from the focal point of the simulation, so I can scale up the focused doggos. With visual effects, I can do all of this without using a GeometryReader. And it automatically adapts to different sizes.

I'd like to share one more example. I've been playing with a feature to send good-dog messages to the people of the dogs I've met. I thought it would be fun to style the dog's name to make it stand out. This is easy now that I can interpolate text with a foreground style right inside another text view. And check it out! I can adjust the styling using these sliders.

Now how does that work? Here's how I'm defining the style. I'm passing my stripeSpacing and angle, along with a color from my asset catalog, to a custom Metal shader. Using SwiftUI's new ShaderLibrary, I can turn Metal shader functions directly into SwiftUI shape styles, like this one that renders the stripes in Furdinand's name.

If you'd like to take Metal shaders out for a spin, just add a new Metal file to your project and call your shader function using ShaderLibrary in SwiftUI. There's another thing in this example that I want to point out. Notice when I hit the end of the tracks on the sliders, the symbol gives this satisfying bounce.

That effect is built in to Slider on macOS and iOS. You can also add it to your own symbols with the new symbol effect modifier. Just apply this modifier to animate an SF Symbol, or all the symbols in a view hierarchy. Symbols support a variety of effects, including continuous animations with pulse and variable color. State changes with scale, appear and disappear, and replace, and event notifications with bounce. Watch "Animate symbols in your app" to learn about the best people-pleasing practices for using symbol effects.

Before leaving this example, I want to point out one last feature. Notice the units on the text here. In the past I might have used small caps for this effect, but now I can get this appearance by applying the new textScale modifier to my units. If Jeff and I bring our app to the Chinese market, the units will be sized correctly, even though the concept of small caps isn't part of the typography in Chinese.

We have another tool to help apps work great in multiple locales. Some languages, like Thai, use taller letter forms. When text from one of these languages is embedded in text localized in a language with shorter letter forms, like English, the taller text can be crowded or clipped. When we know that this might be an issue -- for example, if our dog names were globally crowd-sourced -- we can apply the typesettingLanguage modifier. This lets SwiftUI know that the text might need more space. I'm having so much fun using these new APIs, but it's important to tastefully choose animations to avoid overwhelming people.

To learn about the fundamentals of animation in SwiftUI, check out "Explore SwiftUI animation." Then in "Animate with springs," Jacob will help you build animations that feel at home on everyone's devices. The breadth of new animation APIs in SwiftUI is amazing. I've only scratched the surface here. There's even more to discover, from animation completion handlers to building entirely custom animations. I hope you enjoy these APIs as much as I do.

[Jeff Robertson]

I love how all these new animations and effects really bring our app to life. Now, let's take a look at some of the new interaction APIs for the final touches. Interactions are at the heart of any great app experience, and these are just a few of the updated APIs coming to iOS 17 and aligned releases. My screen of recently met dogs could use a little extra flair to give it that final bit of polish. I'd like to add some visual effects to my dog cards as they transition in and out of the visible area of my scroll view.

The scroll transition modifier is very similar to the visual effect modifier Curt used earlier for the welcome screen. It lets you apply effects to items in your scroll view. Using the scale and opacity effects gave me just that little bit of polish I wanted, with only a few extra lines of code.

I'd also like to add a side-scrolling list of my favorite dog parks to this screen. SwiftUI has added some great features to let me build this. Above my vertical stack of dogs, I'll drop in a horizontal stack for the park cards. I'm using the new containerRelativeFrame modifier to size these park cards relative to the visible size of the horizontal scroll view.

The count specifies how many chunks to divide the screen into. The span says how many of those chunks each view should take. This is pretty great, but I'd like my park cards to snap into place. The new scrollTargetLayout modifier makes that easy. I'll add it to the LazyHStack and modify the scroll view to align to views in the targeted layout.

In addition to view alignment, scroll views can also be defined to use a paging behavior. And for a truly custom experience, you can define your own behavior using the scrollTargetBehavior protocol. I also thought my mutts would deserve a little accolade when they're at the top of the scroll view. The new scrollPosition modifier takes a binding to the topmost item's ID, and it's updated as I scroll. This way, I always know who's top dog.

To learn more about all these and the other great improvements to Scroll View, be sure to watch "Beyond scroll views." Image now supports rendering content with high dynamic range. By applying the allowedDynamicRange modifier, the beautiful images in our app's gallery screen can be shown with their full fidelity. It's best to use this sparingly, though, and usually when the image stands alone.

Apps written with SwiftUI work great with accessibility features out of the box, but you can make them even better with some of the new accessibility APIs we're introducing. The adventurous dog in this photo is a bit too far away to see, so I've applied a magnification gesture to allow zooming in. I'm also going to add the new accessibilityZoomAction modifier to my view. This allows assistive technologies like VoiceOver to access the same functionality without using the gesture. I'll just update the zoom level depending on the action's direction, and I can see what mischief she's been up to now.

[VoiceOver]

Zooming image view. Image.

[Jeff Robertson]

To learn more about all the new accessibility functionality across Apple's platforms, be sure to check out "Build accessible apps with SwiftUI and UIKit." Color now supports using static member syntax to look up custom colors defined in your app's asset catalog. This gives compile-time safety when using them, so you'll never lose time to a typo. For the document app I showed earlier, I've added a menu containing several useful actions to the toolbar. The top section of the menu is a ControlGroup with the new compactMenu style, which shows its items as icons in a horizontal stack.

The tag color selector is defined as a picker with the new palette style. Using this style in concert with symbol images gives a great visual representation in menus, especially one like this where I can use the label's tint to differentiate them. Lastly, the paletteSelectionEffect modifier lets me use a symbol variant to represent the selected item in the picker. With my menu in place, Buddy's dog tag can now be his favorite color, tennis-ball yellow.

Bordered buttons can now be defined with new built-in shapes, such as circle and rounded rectangle. These new border shape styles work on iOS, watchOS, and macOS. Buttons on macOS and iOS can now react to drag actions, like this button in my editor that opens a popover. The new springLoadingBehavior modifier indicates that a button should trigger its action when a drag pauses over it, or when force-clicking it on macOS.

Buttons on tvOS can make great use of the new highlight hover effect. I've used it on our gallery images and applied it just to the image portion of my button's label, to create an effect which feels right at home on the platform. These buttons also use the borderless style, which is now available on tvOS. Hardware keyboards are great for providing an accelerant for common interactions in your app.

Focusable views on platforms with hardware keyboard support can use the onKeyPress modifier to directly react to any keyboard input. The modifier takes a set of keys to match against and an action to perform for the event. To get your fill of focus-related recipes, be sure to watch "The SwiftUI cookbook for focus." From the scroll transitions and behaviors, to button styles and focus interactions, these new APIs can help you build apps with rich functionality and outstanding style.

[Curt Clifton]

I think we've made great progress on our app!

[Jeff Robertson]

It's certainly something.

[Curt Clifton]

It was fun using all these new APIs.

[Jeff Robertson]

That much is true.

[Curt Clifton]

It's an exciting time for SwiftUI. There's a brand-new platform!

[Jeff Robertson]

And the elegance of Observable and SwiftData work so well with SwiftUI.

[Curt Clifton]

The animation improvements are amazing.

[Jeff Robertson]

And don't forget scroll views!

[Curt Clifton]

It's always a thrill to see what our amazing developer community can do with these new APIs.

[Jeff Robertson]

Thanks for watching, everyone. Say hi to your dog for me!

[Curt Clifton]

Keep doing great work!