DEPRECATION NOTICE: This entire page documents the legacy Events system.
For new projects: Use Data Binding instead.
For existing projects: Plan to migrate from Events to Data Binding as soon
as possible. This content is provided for legacy support only.
With Rive events, you have the ability to subscribe to meaningful signals that get reported from animations, state machines, and Rive listeners, all created at design time from the Rive editor. These signals can be subscribed to at runtime and have a specific name, type, and various custom metadata that may accompany the event to help inform the context surrounding its meaning.
For more on the Events feature in general, check out the Events page in the editor section of the docs. The Event system has also been expanded to support Audio Events to trigger audio to play in the editor and at runtime.
For example, in a Rive graphic simulating a loader, there may be an event named LoadComplete fired when transitioning from a complete timeline animation state to an idle state. You can subscribe to Rive events with a callback that the runtime may invoke, and from there, your callback can handle extra functionality at just the right moment when the event fired.
Other practical use cases for events:
- Coordinating audio playback at specific moments in an animation, see Audio Events
- Opening a URL when specific interactions have occurred
- Adding haptic feedback on meaningful touch interactions
- Implementing functionality on Buttons and other UI elements
- Send semantic information
- Communicate any information your runtime needs at the right moment
Subscribing to Events
When you subscribe to Rive events at runtime, you subscribe to all Rive events that may be emitted from a state machine, and you can parse through each event by name or type to execute conditional logic.
Let’s use a 5-star rater Rive example to set any text supplied with events and open a URL if one is given.
Subscribing to Events via State Machine Delegate
To subscribe to Rive events, implement the onRiveEventReceived protocol from StateMachineDelegate.
@objc optional func onRiveEventReceived(onRiveEvent riveEvent: RiveEvent)
This implementation may be invoked when a Rive event is fired from the render loop and provides a generic RiveEvent data type, of which you can type check to cast to a specific event for further parsing, such as a RiveGeneralEvent or a RiveOpenUrlEvent.
For example:
@objc func onRiveEventReceived(onRiveEvent riveEvent: RiveEvent) {
debugPrint("Event Name: \(riveEvent.name())")
debugPrint("Event Type: \(riveEvent.type())")
if let openUrlEvent = riveEvent as? RiveOpenUrlEvent {
// i.e., open the URL
} else if let generalEvent = riveEvent as? RiveGeneralEvent {
// i.e., print the string data provided in a Text widget
}
}
Note: Events of type RiveOpenUrlEvent will not automatically open links in the user’s preferred browser. You will need to add the logic to grab the url property of the riveEvent passed into the delegate and open the link.
Example Usage
import SwiftUI
import RiveRuntime
struct SwiftEvents: DismissableView {
var dismiss: () -> Void = {}
@StateObject private var rvm = RiveEventsVMExample()
var body: some View {
VStack {
rvm.view()
Text("Event Message")
.font(.headline)
.padding(.bottom, 10)
Text(rvm.eventText)
.padding()
.background(rvm.eventText.isEmpty ? Color.clear : Color.black)
.foregroundColor(.white)
.cornerRadius(10)
}
}
}
class RiveEventsVMExample: RiveViewModel {
@Published var eventText = ""
init() {
super.init(fileName: "rating_animation")
}
func view() -> some View {
return super.view().frame(width: 400, height: 400, alignment: .center)
}
// Subscribe to Rive events and this delegate will be invoked
@objc func onRiveEventReceived(onRiveEvent riveEvent: RiveEvent) {
if let openUrlEvent = riveEvent as? RiveOpenUrlEvent {
if let url = URL(string: openUrlEvent.url()) {
#if os(iOS)
UIApplication.shared.open(url)
#else
NSWorkspace.shared.open(url)
#endif
}
} else if let generalEvent = riveEvent as? RiveGeneralEvent {
let genEventProperties = generalEvent.properties();
if let msg = genEventProperties["message"] {
eventText = msg as! String
}
}
}
}
Additional Resources