Skip to content

Commit

Permalink
Fixes crashes with unknown layer states, adds SwiftUI state machine e…
Browse files Browse the repository at this point in the history
…xample, tidies up file layout for SwiftUI
  • Loading branch information
mjohnsullivan committed May 15, 2021
1 parent 640ce4e commit b2e6939
Show file tree
Hide file tree
Showing 20 changed files with 203 additions and 54 deletions.
Binary file added Example-iOS/Assets/life_bar.riv
Binary file not shown.
Binary file added Example-iOS/Assets/liquid.riv
Binary file not shown.
80 changes: 64 additions & 16 deletions Example-iOS/RiveExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,20 @@
04A8F6C526454711002C909A /* LoopMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A8F6C426454711002C909A /* LoopMode.swift */; };
04BE5438264D604500427B39 /* iosPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BE5437264D604500427B39 /* iosPlayer.swift */; };
04C4C83E2646FE410047E614 /* StateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C4C83D2646FE410047E614 /* StateMachine.swift */; };
C9A84F38264495600014D8E0 /* ExampleUIRiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A84F37264495600014D8E0 /* ExampleUIRiveView.swift */; };
C9A84F38264495600014D8E0 /* RiveExplorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A84F37264495600014D8E0 /* RiveExplorer.swift */; };
C9A84F5E2644A75A0014D8E0 /* ExamplesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A84F5D2644A75A0014D8E0 /* ExamplesViewController.swift */; };
C9A84F602644AB6B0014D8E0 /* RiveViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A84F5F2644AB6B0014D8E0 /* RiveViewWrapper.swift */; };
C9A84F602644AB6B0014D8E0 /* RiveExplorerBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A84F5F2644AB6B0014D8E0 /* RiveExplorerBridge.swift */; };
C9BD3926263B5FC700696C37 /* truck_v7.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9BD3925263B5FC700696C37 /* truck_v7.riv */; };
C9C73E9824FC471E00EF9516 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C73E9724FC471E00EF9516 /* AppDelegate.swift */; };
C9C73E9A24FC471E00EF9516 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C73E9924FC471E00EF9516 /* SceneDelegate.swift */; };
C9C73E9E24FC471E00EF9516 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C9C73E9D24FC471E00EF9516 /* Assets.xcassets */; };
C9C73EA124FC471E00EF9516 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C9C73EA024FC471E00EF9516 /* Preview Assets.xcassets */; };
C9CB2F13264C92D200E7FF0D /* ExampleStateMachineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CB2F12264C92D200E7FF0D /* ExampleStateMachineView.swift */; };
C9CB2F13264C92D200E7FF0D /* RiveComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CB2F12264C92D200E7FF0D /* RiveComponents.swift */; };
C9CE8266263B90E000F98DDB /* juice_v7.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9CE8265263B90E000F98DDB /* juice_v7.riv */; };
C9D3DE5B264F3B51001BA265 /* liquid.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9D3DE5A264F3B51001BA265 /* liquid.riv */; };
C9D3DE5E264F3B72001BA265 /* RiveProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D3DE5D264F3B72001BA265 /* RiveProgressBar.swift */; };
C9D3DE60264F3B84001BA265 /* RiveProgressBarBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D3DE5F264F3B84001BA265 /* RiveProgressBarBridge.swift */; };
C9D3DE68264F49F4001BA265 /* life_bar.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9D3DE67264F49F4001BA265 /* life_bar.riv */; };
C9E04099264DD4F5009ABC7C /* RiveButtonBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E04098264DD4F5009ABC7C /* RiveButtonBridge.swift */; };
C9E0409D264DEAA2009ABC7C /* RiveButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E0409C264DEAA2009ABC7C /* RiveButton.swift */; };
C9E0409F264DF1A3009ABC7C /* RiveSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E0409E264DF1A3009ABC7C /* RiveSwitch.swift */; };
Expand Down Expand Up @@ -109,18 +113,22 @@
04A8F6C426454711002C909A /* LoopMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopMode.swift; sourceTree = "<group>"; };
04BE5437264D604500427B39 /* iosPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iosPlayer.swift; sourceTree = "<group>"; };
04C4C83D2646FE410047E614 /* StateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateMachine.swift; sourceTree = "<group>"; };
C9A84F37264495600014D8E0 /* ExampleUIRiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleUIRiveView.swift; sourceTree = "<group>"; };
C9A84F37264495600014D8E0 /* RiveExplorer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveExplorer.swift; sourceTree = "<group>"; };
C9A84F5D2644A75A0014D8E0 /* ExamplesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExamplesViewController.swift; sourceTree = "<group>"; };
C9A84F5F2644AB6B0014D8E0 /* RiveViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveViewWrapper.swift; sourceTree = "<group>"; };
C9A84F5F2644AB6B0014D8E0 /* RiveExplorerBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveExplorerBridge.swift; sourceTree = "<group>"; };
C9BD3925263B5FC700696C37 /* truck_v7.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = truck_v7.riv; sourceTree = "<group>"; };
C9C73E9424FC471E00EF9516 /* RiveExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RiveExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
C9C73E9724FC471E00EF9516 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C9C73E9924FC471E00EF9516 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
C9C73E9D24FC471E00EF9516 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
C9C73EA024FC471E00EF9516 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
C9C73EA524FC471E00EF9516 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C9CB2F12264C92D200E7FF0D /* ExampleStateMachineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleStateMachineView.swift; sourceTree = "<group>"; };
C9CB2F12264C92D200E7FF0D /* RiveComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveComponents.swift; sourceTree = "<group>"; };
C9CE8265263B90E000F98DDB /* juice_v7.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = juice_v7.riv; sourceTree = "<group>"; };
C9D3DE5A264F3B51001BA265 /* liquid.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = liquid.riv; sourceTree = "<group>"; };
C9D3DE5D264F3B72001BA265 /* RiveProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveProgressBar.swift; sourceTree = "<group>"; };
C9D3DE5F264F3B84001BA265 /* RiveProgressBarBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveProgressBarBridge.swift; sourceTree = "<group>"; };
C9D3DE67264F49F4001BA265 /* life_bar.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = life_bar.riv; sourceTree = "<group>"; };
C9E04098264DD4F5009ABC7C /* RiveButtonBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveButtonBridge.swift; sourceTree = "<group>"; };
C9E0409C264DEAA2009ABC7C /* RiveButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveButton.swift; sourceTree = "<group>"; };
C9E0409E264DF1A3009ABC7C /* RiveSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveSwitch.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -181,6 +189,8 @@
042C88D02644447500E7DBB2 /* f22.riv */,
042C88D12644447500E7DBB2 /* flux_capacitor.riv */,
C9CE8265263B90E000F98DDB /* juice_v7.riv */,
C9D3DE67264F49F4001BA265 /* life_bar.riv */,
C9D3DE5A264F3B51001BA265 /* liquid.riv */,
042C88D62644447500E7DBB2 /* loopy.riv */,
042C88CD2644447400E7DBB2 /* mascot.riv */,
042C88D22644447500E7DBB2 /* neostream.riv */,
Expand All @@ -202,13 +212,11 @@
C9A84F342644931E0014D8E0 /* SwiftUI */ = {
isa = PBXGroup;
children = (
C9A84F37264495600014D8E0 /* ExampleUIRiveView.swift */,
C9A84F5F2644AB6B0014D8E0 /* RiveViewWrapper.swift */,
C9CB2F12264C92D200E7FF0D /* ExampleStateMachineView.swift */,
C9E04098264DD4F5009ABC7C /* RiveButtonBridge.swift */,
C9E0409C264DEAA2009ABC7C /* RiveButton.swift */,
C9E0409E264DF1A3009ABC7C /* RiveSwitch.swift */,
C9E040A6264DF95C009ABC7C /* RiveSwitchBridge.swift */,
C9D3DE5C264F3B5C001BA265 /* ProgressBar */,
C9D3DE59264F309F001BA265 /* Explorer */,
C9D3DE58264F308B001BA265 /* Switch */,
C9D3DE55264F3080001BA265 /* Button */,
C9CB2F12264C92D200E7FF0D /* RiveComponents.swift */,
);
path = SwiftUI;
sourceTree = "<group>";
Expand Down Expand Up @@ -263,6 +271,42 @@
name = Frameworks;
sourceTree = "<group>";
};
C9D3DE55264F3080001BA265 /* Button */ = {
isa = PBXGroup;
children = (
C9E0409C264DEAA2009ABC7C /* RiveButton.swift */,
C9E04098264DD4F5009ABC7C /* RiveButtonBridge.swift */,
);
path = Button;
sourceTree = "<group>";
};
C9D3DE58264F308B001BA265 /* Switch */ = {
isa = PBXGroup;
children = (
C9E0409E264DF1A3009ABC7C /* RiveSwitch.swift */,
C9E040A6264DF95C009ABC7C /* RiveSwitchBridge.swift */,
);
path = Switch;
sourceTree = "<group>";
};
C9D3DE59264F309F001BA265 /* Explorer */ = {
isa = PBXGroup;
children = (
C9A84F37264495600014D8E0 /* RiveExplorer.swift */,
C9A84F5F2644AB6B0014D8E0 /* RiveExplorerBridge.swift */,
);
path = Explorer;
sourceTree = "<group>";
};
C9D3DE5C264F3B5C001BA265 /* ProgressBar */ = {
isa = PBXGroup;
children = (
C9D3DE5D264F3B72001BA265 /* RiveProgressBar.swift */,
C9D3DE5F264F3B84001BA265 /* RiveProgressBarBridge.swift */,
);
path = ProgressBar;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -345,6 +389,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C9D3DE5B264F3B51001BA265 /* liquid.riv in Resources */,
042C88DF2644447500E7DBB2 /* mascot.riv in Resources */,
C9BD3926263B5FC700696C37 /* truck_v7.riv in Resources */,
042C88DC2644447500E7DBB2 /* pull.riv in Resources */,
Expand All @@ -367,6 +412,7 @@
042C88E22644447500E7DBB2 /* f22.riv in Resources */,
042C88EC2644447500E7DBB2 /* vader.riv in Resources */,
C9C73E9E24FC471E00EF9516 /* Assets.xcassets in Resources */,
C9D3DE68264F49F4001BA265 /* life_bar.riv in Resources */,
042C88DB2644447500E7DBB2 /* wacky.riv in Resources */,
042C88EB2644447500E7DBB2 /* clipping.riv in Resources */,
);
Expand All @@ -380,20 +426,22 @@
buildActionMask = 2147483647;
files = (
C9C73E9824FC471E00EF9516 /* AppDelegate.swift in Sources */,
C9CB2F13264C92D200E7FF0D /* ExampleStateMachineView.swift in Sources */,
C9CB2F13264C92D200E7FF0D /* RiveComponents.swift in Sources */,
042C888E2644230700E7DBB2 /* utility.swift in Sources */,
C9E0409F264DF1A3009ABC7C /* RiveSwitch.swift in Sources */,
C9D3DE5E264F3B72001BA265 /* RiveProgressBar.swift in Sources */,
042C88902644250D00E7DBB2 /* MultipleAnimations.swift in Sources */,
C9E040A7264DF95C009ABC7C /* RiveSwitchBridge.swift in Sources */,
C9A84F38264495600014D8E0 /* ExampleUIRiveView.swift in Sources */,
C9A84F38264495600014D8E0 /* RiveExplorer.swift in Sources */,
04A8F6C526454711002C909A /* LoopMode.swift in Sources */,
C9C73E9A24FC471E00EF9516 /* SceneDelegate.swift in Sources */,
C9E04099264DD4F5009ABC7C /* RiveButtonBridge.swift in Sources */,
04C4C83E2646FE410047E614 /* StateMachine.swift in Sources */,
04BE5438264D604500427B39 /* iosPlayer.swift in Sources */,
C9A84F5E2644A75A0014D8E0 /* ExamplesViewController.swift in Sources */,
042C888C2643EEE300E7DBB2 /* Layout.swift in Sources */,
C9A84F602644AB6B0014D8E0 /* RiveViewWrapper.swift in Sources */,
C9A84F602644AB6B0014D8E0 /* RiveExplorerBridge.swift in Sources */,
C9D3DE60264F3B84001BA265 /* RiveProgressBarBridge.swift in Sources */,
042C88882643DB7100E7DBB2 /* SimpleAnimation.swift in Sources */,
C9E0409D264DEAA2009ABC7C /* RiveButton.swift in Sources */,
);
Expand Down
4 changes: 2 additions & 2 deletions Example-iOS/Source/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jrC-Ng-Q2K">
<rect key="frame" x="0.0" y="221" width="414" height="30"/>
<state key="normal" title="Animation SwiftUI"/>
<state key="normal" title="Rive Explorer"/>
<connections>
<segue destination="w39-2n-FCH" kind="presentation" destinationCreationSelector="hostingAction:" id="SeF-el-OxU"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Y5d-hg-cnK">
<rect key="frame" x="0.0" y="251" width="414" height="30"/>
<state key="normal" title="SwiftUI Controls"/>
<state key="normal" title="SwiftUI Components"/>
<connections>
<segue destination="yNC-ze-bA4" kind="presentation" destinationCreationSelector="hostingActionStateMachine:" id="9dn-S5-TjE"/>
</connections>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ struct RiveButton: View {
.frame(width: 100, height: 20)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
.onTapGesture {
print("Rive button click")
play = true
action?()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import SwiftUI
import RiveRuntime

struct ExampleUIRiveView: View {
struct RiveExplorer: View {
@ObservedObject private var riveController = RiveController(
"artboard_animations",
fit: Fit.fitCover
Expand All @@ -13,7 +13,7 @@ struct ExampleUIRiveView: View {

var body: some View {
ZStack(alignment: .bottomLeading) {
UIRiveView(
RiveExplorerBridge(
controller: riveController
)
VStack {
Expand Down Expand Up @@ -153,6 +153,6 @@ struct ExampleUIRiveView: View {

struct RiveSwiftUIView_Previews: PreviewProvider {
static var previews: some View {
ExampleUIRiveView()
RiveExplorer()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class RiveController: ObservableObject {
}
}

struct UIRiveView: UIViewRepresentable {
struct RiveExplorerBridge: UIViewRepresentable {

// MARK: - Properties

Expand Down Expand Up @@ -102,7 +102,7 @@ struct UIRiveView: UIViewRepresentable {
}

/// Called when the view model changes
func updateUIView(_ uiView: RiveView, context: UIViewRepresentableContext<UIRiveView>) {
func updateUIView(_ uiView: RiveView, context: UIViewRepresentableContext<RiveExplorerBridge>) {
// Set the properties
uiView.fit = controller.fit
uiView.alignment = controller.alignment
Expand Down Expand Up @@ -142,7 +142,7 @@ struct UIRiveView: UIViewRepresentable {
}
}

extension UIRiveView {
extension RiveExplorerBridge {

// MARK: - Coordinator

Expand Down
31 changes: 31 additions & 0 deletions Example-iOS/Source/SwiftUI/ProgressBar/RiveProgressBar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// RiveProgressBar.swift
// RiveExample
//
// Created by Matt Sullivan on 5/14/21.
// Copyright © 2021 Rive. All rights reserved.
//

import SwiftUI

struct RiveProgressBar: View {

let resource: String

@Binding var health: Double

var body: some View {
VStack {
RiveProgressBarBridge(health: $health)
.frame(width: 300, height: 75)
}
}
}

struct RiveProgressBar_Previews: PreviewProvider {
static var previews: some View {


RiveProgressBar(resource: "liquid", health: Binding.constant(50.0))
}
}
43 changes: 43 additions & 0 deletions Example-iOS/Source/SwiftUI/ProgressBar/RiveProgressBarBridge.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import SwiftUI
import RiveRuntime

struct RiveProgressBarBridge: UIViewRepresentable {
let resource: String = "life_bar"
var fit: Fit = .fitFill
var alignment: RiveRuntime.Alignment = .alignmentCenter
var stateMachine: String = "Life Machine"

@Binding var health: Double

/// The inputs
private let input100Name = "100"
private let input75Name = "75"
private let input50Name = "50"
private let input25Name = "25"
private let input0Name = "0"

/// Constructs the view
func makeUIView(context: Context) -> RiveView {
let riveView = RiveView(
riveFile: getRiveFile(resourceName: resource),
fit: fit,
alignment: alignment,
autoplay: true,
stateMachine: stateMachine
)

// Always keep the 100 set; just how this state machine works
riveView.setBooleanState(stateMachine, inputName: input100Name, value: true)

return riveView
}



func updateUIView(_ riveView: RiveView, context: UIViewRepresentableContext<RiveProgressBarBridge>) {
riveView.setBooleanState(stateMachine, inputName: input75Name, value: health < 100)
riveView.setBooleanState(stateMachine, inputName: input50Name, value: health <= 66)
riveView.setBooleanState(stateMachine, inputName: input25Name, value: health <= 33)
riveView.setBooleanState(stateMachine, inputName: input0Name, value: health <= 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
import SwiftUI
import RiveRuntime

struct ExampleStateMachineView: View {
struct RiveComponents: View {

/// lets UIKit bind to this to trigger dismiss events
var dismiss: () -> Void = {}

/// Plays or pauses the Rive animation
/// Plays or pauses the button's Rive animation
@State var play: Bool = false

/// Tracks the health value coming from the slide for the progress bar
@State var health: Double = 100

var body: some View {
VStack {
HStack {
Expand All @@ -31,6 +34,15 @@ struct ExampleStateMachineView: View {
print("switch is \(on ? "on" : "off")")
}
}
VStack {
Text("RiveProgressBar:")
RiveProgressBar(resource: "liquid", health: $health)
}
Slider(
value: $health,
in: 0...100
)
.padding()
}
}
}
Expand Down Expand Up @@ -136,6 +148,6 @@ struct ExampleStateMachineView: View {

struct ExampleStateMachineView_Previews: PreviewProvider {
static var previews: some View {
ExampleStateMachineView()
RiveComponents()
}
}
File renamed without changes.
Loading

0 comments on commit b2e6939

Please sign in to comment.