View Models
View models describe a set of properties, but cannot themselves be used to get or set values - that is the role of view model instances. To begin, we need to get a reference to a particular view model. This can be done either by index, by name, or the default for a given artboard, and is done from the Rive file. The default option refers to the view model assigned to an artboard by the dropdown in the editor.- New Runtime
- Legacy Runtime
View models are not their own type; rather, they are a source when creating a view model instance from a These sources are used in conjunction with getting a view model instance. See View Model Instances for more information.
File.You can define the source of a view model via the ViewModelSource type.View Model Instances
Once we have a reference to a view model, it can be used to create an instance. When creating an instance, you have four options:-
Create a blank instance - Fill the properties of the created instance with default values as follows:
- Create the default instance - Use the instance labelled “Default” in the editor. Usually this is the one a designer intends as the primary one to be used at runtime.
- Create by index - Using the order returned when iterating over all available instances. Useful when creating multiple instances by iteration.
- Create by name - Use the editor’s instance name. Useful when creating a specific instance.
In some samples, due to the wordiness of “view model instance”, we use the abbreviation “VMI”, as well as “VM” for “view model”.
- New Runtime
- Legacy Runtime
The following section assumes that you have read through the Apple overview.
Binding
The created instance can then be assigned to a state machine or artboard. This establishes the bindings set up at edit time. It is preferred to assign to a state machine, as this will automatically apply the instance to the artboard as well. Only assign to an artboard if you are not using a state machine, i.e. your file is static or uses linear animations.The initial values of the instance are not applied to their bound elements until the state machine or artboard advances.
- New Runtime
- Legacy Runtime
Create and retain the instance you want to read, observe, or modify, then bind it when creating the state machine. Run setup from a To replace the main instance later, create a new instance and use the async throwing binding API:After binding succeeds, retain
@MainActor async context.replacementInstance for subsequent property access.The Rive initializer with an explicit artboard and state machine uses those components as configured, without rebinding. Create the artboard from the same file and the state machine from that artboard. Use compatible instances from the same file and worker.Auto-Binding
Alternatively, you may prefer to use auto-binding. This will automatically bind the default view model of the artboard using the default instance to both the state machine and the artboard. The default view model is the one selected on the artboard in the editor dropdown. The default instance is the one marked “Default” in the editor.- New Runtime
- Legacy Runtime
State machine creation binds authored main and global defaults when available. If you do not need programmatic access to those instances, use a convenience initializer:To choose an artboard and use its default state machine:Automatically created instances have no public getters. If you need to read or change their properties, create and retain instances explicitly as shown in Binding.
Global View Models
In the new Apple runtime, global view models provide shared data, such as a theme, to bindings authored to use that global. Create instances and bind them by their global view model names:try await file.getGlobalViewModelNames().
In this example, keep main and theme in your app’s model if you need to access their properties. Global instances use the same property and observation APIs as the main instance. To share an instance across state machines from the same file, bind that same instance to each state machine.
You can replace only a global binding later:
if, if let, and for statements. For example, choose between instances named “Light” and “Dark” authored on the “Theme” view model:
main: to update main and global bindings in one call. Each call sets the supplied bindings; it does not replace the complete set of bindings. Omitting a global does not remove it or clear its instance—the existing binding stays in place. Slots without an existing or supplied instance receive authored defaults when available. Passing nil for main also preserves its existing binding rather than clearing it.
All supplied global names are checked before applying any supplied bindings. An unknown or non-global name throws StateMachineError.invalidGlobalViewModelName; duplicate names in one call throw StateMachineError.duplicateGlobalViewModelInstance. These rejected calls leave existing bindings intact. Metadata failures throw StateMachineError.error, and cancellation throws StateMachineError.cancelled. Name validation does not check instance type or worker compatibility.
Properties
A property is a value that can be read, set, or observed on a view model instance. Properties can be of the following types:
For more information on version compatibility, see the Feature Support page.
Listing properties
Property descriptors can be inspected on a view model to discover at runtime which are available. These are not the mutable properties themselves though - once again those are on instances. These descriptors have a type and name.- New Runtime
- Legacy Runtime
Reading and writing properties
References to these properties can be retrieved by name or path. Some properties are mutable and have getters, setters, and observer operations for their values. Getting or observing the value will retrieve the latest value set on that property’s binding, as of the last state machine or artboard advance. Setting the value will update the value and all of its bound elements.After setting a property’s value, the changes will not apply to their bound elements until the state machine or artboard advances.
- New Runtime
- Legacy Runtime
Property types are a very thin wrapper around the path and return type of a property.All property APIs (e.g setters, getters, and triggers) are available as part of a
ViewModelInstance object.Nested property paths
View models can have properties of type view model, allowing for arbitrary nesting. You can chain property calls on each instance starting from the root until you get to the property of interest. Alternatively, you can do this through a path parameter, which is similar to a URI in that it is a forward slash delimited list of property names ending in the name of the property of interest.- New Runtime
- Legacy Runtime
Property types are no longer reference types, and require the name or full path to a property when initializing the property value type. There is no longer an API to chain nested properties.See Properties for usage details.
Observability
You can observe changes over time to property values, either by using listeners or a platform equivalent method. Once observed, you will be notified when the property changes are applied by a state machine advance, whether that is a new value that has been explicitly set or if the value was updated as a result of a binding.- New Runtime
- Legacy Runtime
RiveController automatically redraws after changes to bound main and global instances, including nested and list child instances. You do not need to subscribe to the deprecated dirtyStream() API to request redraws. Use property streams to react to values in your app.Property listeners utilize Swift Concurrency’s async throwing stream API. If a property returns a value, you can listen to its changes by calling the valueStream(of:) method on a ViewModelInstance object.stream(of:) method on a ViewModelInstance object. This returns a stream of Void values, which can be ignored.Images
Image properties let you set and replace raster images at runtime, with each instance of the image managed independently. For example, you could build an avatar creator and dynamically update features — like swapping out a hat — by setting a view model’s image property.- New Runtime
- Legacy Runtime
To set an image, you first need to decode an image from a
Worker. This has to be the Worker that was used when initializing a File, from which you are setting the image property of a view model instance.Lists
List properties let you manage a dynamic set of view model instances at runtime. For example, you can build a to-do app where users can add and remove tasks in a scrollable Layout. See the Editor section on creating data bound lists. A single list property can include different view model types, with each view model tied to its own Component, making it easy to populate a list with a variety of Component instances. With list properties, you can:- Add a new view model instance (optionally at an index)
- Remove an existing view model instance (optionally by index)
- Swap two view model instances by index
- Get the size of a list
- New Runtime
- Legacy Runtime
Artboards
Artboard properties allows you to swap out entire components at runtime. This is useful for creating modular components that can be reused across different designs or applications, for example:- Creating a skinning system that supports a large number of variations, such as a character creator where you can swap out different body parts, clothing, and accessories.
- Creating a complex scene that is a composition of various artboards loaded from various different Rive files (drawn to a single canvas/texture/widget).
- Reducing the size (complexity) of a single Rive file by breaking it up into smaller components that can be loaded on demand and swapped in and out as needed.
- New Runtime
- Legacy Runtime