Give your simulator superpowers

RocketSim: An Essential Developer Tool
as recommended by Apple

Exclusive Pre-Launch Offer: Get 20% Off atgoing-indie.com

@Previewable: Dynamic SwiftUI Previews Made Easy

Xcode 16 introduced the @Previewable macro for SwiftUI Previews, allowing you to use dynamic properties inline in previews. You’ll be able to make richer and more dynamic previews of your SwiftUI views without the need to wrap any state inside child views.

Swift and SwiftUI use macros to hide implementation details, and this new attached-macro is a perfect example of reducing boilerplate. Before diving deeper into this new SwiftUI macro, ensure to read Swift Macros: Extend Swift with New Kinds of Expressions and #Preview SwiftUI Views using Macros.

What is the @Previewable macro?

When you’ve used the #Preview macro before, you’ve likely been running into cases where you couldn’t define local state variables. These variables are helpful when you want to test your views dynamically inside SwiftUI Previews.

For example, you might have a preview representing a toggle:

#Preview("On") {
    Toggle("Enable slow animations", isOn: .constant(true))
}

#Preview("Off") {
    Toggle("Enable slow animations", isOn: .constant(false))
}

As you can see, we defined two separate previews to represent each toggle state. This will also be reflected inside SwiftUI’s preview navigator with an “On” and “Off” tab to switch views. Unfortunately, there wasn’t a way to save the local state unless we wrapped the toggle inside a container view:

struct TogglePreviewContainer: View {
    @State private var isOn: Bool = false
    
    var body: some View {
        Toggle("Enable slow animations", isOn: $isOn)
    }
}

#Preview("Dynamic") {
    TogglePreviewContainer()
}

This results in boilerplate code we rather not write, so the SwiftUI team decided to introduce a new @Previewable macro instead:

#Preview("New in Xcode 16") {
    /// Using `@Previewable`, you can use dynamic properties inline.
    @Previewable @State var isOn: Bool = false
    
    Toggle("Enable slow animations", isOn: $isOn)
}

Tagging a variable with the previewable macro lets you use dynamic properties inside SwiftUI previews. In other words, you’ll be able to interact with your toggle directly and see how it works:

An interactive SwiftUI Preview using @Previewable compared to a static preview.

The video demonstrates how the SwiftUI preview became interactive, compared to the earlier defined previews that are unresponsive.

Stay updated with the latest in SwiftUI

Join 19,800 Swift developers in our exclusive newsletter for the latest insights, tips, and updates. Don't miss out – join today!

You can always unsubscribe, no hard feelings.

How does the @Previewable macro work?

Underneath, the macro writes similar code to what we did manually before. As we learned in Swift Macros: Extend Swift with New Kinds of Expressions, we can peek behind the macro and see what code it generated:

The @Previewable macro wraps your preview inside a view to allow local state properties.
The @Previewable macro wraps your preview inside a view to allow local state properties.

As you can see, the macro generated a __P_Previewable_Transform_Wrapper SwiftUI view that wraps our toggle. Tagged declarations become properties on the view, and all remaining statements form the view’s body. Altogether, this new macro reduces boilerplate code and allows you to write compact and interactive SwiftUI previews.

Conclusion

Xcode 16 improves how we can define SwiftUI previews for views containing state. We no longer have to wrap our elements inside custom containers, but we can directly interact with properties using the @Previewable macro.

If you want to improve your SwiftUI knowledge, even more, check out the SwiftUI category page. Feel free to contact me or tweet me on Twitter if you have any additional tips or feedback.

Thanks!

 
Antoine van der Lee

Written by

Antoine van der Lee

iOS Developer since 2010, former Staff iOS Engineer at WeTransfer and currently full-time Indie Developer & Founder at SwiftLee. Writing a new blog post every week related to Swift, iOS and Xcode. Regular speaker and workshop host.