RealityKit Basics: update closure
The update closure will run when any referenced state changes. We can reach into our RealityView content to modify entities or components.
Overview
We touched on the update closure in the post on RealityView, but let’s take a closer look. The update closure is our bridge from the 3D world of RealityKit to SwiftUI. There are three concepts we need use to make this work for us.
- Some state for our view. This could be simple
@Statevariables like in this example, or more complex data defined where in our app. - Something to modify the state. In this example, we have two toggle buttons in the toolbar.
- The
updateclosure. Any code we define here will execute whenever the update closure is triggered.
When is update triggered? Generally speaking †, whenever one of or more bit of referenced state is modified. For example, this will only run when showEarth or showMoon has changed. If we had a third state variable called showSun, changes to it would not trigger this since we are not using it in the closure.
} update: { content in
if let earth = content.entities.first?.findEntity(named: "Earth"), let moon = content.entities.first?.findEntity(named: "Moon") {
earth.isEnabled = showEarth
moon.isEnabled = showMoon
}
}We can access the content from RealityView, then query the entity graph to find something that needs to change.
It’s important to note that this update closure is not like an update or tick function in a game engine. Those run every frame, whereas this only runs when the state it references changes.
Something else to keep in mind is that this whole closure will fire when any state it uses has changed. If either showEarth or showMoon is changed, this update will be triggered. If you have very complex views with a lot of state, you may run into situations where entities updated unnecessarily.
Lastly, update will fire every time a bit if state is modified. If the action you are performing is complex, that may not be idea. For example, I’d avoid using sliders or other controls that rapidly change state variables, as each change would trigger an update.
In a future post, we’ll look at some other methods to update our entities based on changes to state.
Video Demo
Full Example Code
struct Example049: View {
// 1. We'll watch these state variables
@State var showMoon = true
@State var showEarth = true
var body: some View {
RealityView { content in
if let scene = try? await Entity(named: "RKBasicsLoading", in: realityKitContentBundle) {
content.add(scene)
scene.position.y = -0.4
}
} update: { content in
// 3. Find the Earth and Moon entities and update their visibility based on our state
if let earth = content.entities.first?.findEntity(named: "Earth"), let moon = content.entities.first?.findEntity(named: "Moon") {
earth.isEnabled = showEarth
moon.isEnabled = showMoon
}
}
// 2. SwiftUI toolbar and toggles to modify our state
.toolbar {
ToolbarItem(placement: .bottomOrnament, content: {
HStack {
Toggle("Show Earth", isOn: $showEarth)
.toggleStyle(.button)
Toggle("Show Moon", isOn: $showMoon)
.toggleStyle(.button)
}
})
}
}
}I’ve seen some cases where other changes to the view cause this closure to run. I’ve also see cases where using a state variable directly is not enough to trigger update. I suspect those were visionOS bugs that have since been solved.
Support our work so we can continue to bring you new examples and articles.
Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Follow Step Into Vision