Added Swift View/Controller to example; updated cpp

This commit is contained in:
Matt Sullivan
2020-10-05 14:29:41 -07:00
parent 8479d9c4f8
commit eb883069c3
7 changed files with 177 additions and 50 deletions

Binary file not shown.

View File

@@ -8,7 +8,6 @@
/* Begin PBXBuildFile section */
C9696B1224FC704A0041502A /* juice.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9696B1124FC704A0041502A /* juice.riv */; };
C9696B1524FC71CE0041502A /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9696B1424FC71CE0041502A /* Utilities.swift */; };
C970484A250822F300CB3AB3 /* simple.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9704847250822F300CB3AB3 /* simple.riv */; };
C98F298B2513FD8C0076E802 /* blend.riv in Resources */ = {isa = PBXBuildFile; fileRef = C98F29882513FD8C0076E802 /* blend.riv */; };
C9927C1B250986BF009F17F5 /* truck.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9927C18250986BF009F17F5 /* truck.riv */; };
@@ -16,6 +15,8 @@
C99E2FE8251E8E35009227CA /* bird.riv in Resources */ = {isa = PBXBuildFile; fileRef = C99E2FE6251E8E35009227CA /* bird.riv */; };
C99E2FE9251E8E35009227CA /* funtime.riv in Resources */ = {isa = PBXBuildFile; fileRef = C99E2FE7251E8E35009227CA /* funtime.riv */; };
C9A7D7F52523C1D900AFB875 /* sheep.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9A7D7F22523C1D900AFB875 /* sheep.riv */; };
C9C1DF7F252BA5EF00B0A444 /* MyRiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C1DF7E252BA5EF00B0A444 /* MyRiveView.swift */; };
C9C1DF83252BA62800B0A444 /* MyRiveViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C1DF82252BA62800B0A444 /* MyRiveViewController.swift */; };
C9C73E9824FC471E00EF9516 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C73E9724FC471E00EF9516 /* AppDelegate.swift */; };
C9C73E9A24FC471E00EF9516 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C73E9924FC471E00EF9516 /* SceneDelegate.swift */; };
C9C73E9C24FC471E00EF9516 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9C73E9B24FC471E00EF9516 /* ContentView.swift */; };
@@ -24,6 +25,7 @@
C9C73EA424FC471E00EF9516 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C9C73EA224FC471E00EF9516 /* LaunchScreen.storyboard */; };
C9E1AA45251E957F00BD52EC /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9E1AA3E251E94CC00BD52EC /* RiveRuntime.framework */; };
C9E1AA46251E957F00BD52EC /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C9E1AA3E251E94CC00BD52EC /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
C9EEA13125268E48001BB768 /* teeny.riv in Resources */ = {isa = PBXBuildFile; fileRef = C9EEA12E25268E48001BB768 /* teeny.riv */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -59,7 +61,6 @@
/* Begin PBXFileReference section */
C9696B1124FC704A0041502A /* juice.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = juice.riv; sourceTree = "<group>"; };
C9696B1424FC71CE0041502A /* Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = "<group>"; };
C9704847250822F300CB3AB3 /* simple.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = simple.riv; sourceTree = "<group>"; };
C98F29882513FD8C0076E802 /* blend.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = blend.riv; sourceTree = "<group>"; };
C9927C18250986BF009F17F5 /* truck.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = truck.riv; sourceTree = "<group>"; };
@@ -67,6 +68,8 @@
C99E2FE6251E8E35009227CA /* bird.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = bird.riv; sourceTree = "<group>"; };
C99E2FE7251E8E35009227CA /* funtime.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = funtime.riv; sourceTree = "<group>"; };
C9A7D7F22523C1D900AFB875 /* sheep.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = sheep.riv; sourceTree = "<group>"; };
C9C1DF7E252BA5EF00B0A444 /* MyRiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyRiveView.swift; sourceTree = "<group>"; };
C9C1DF82252BA62800B0A444 /* MyRiveViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyRiveViewController.swift; 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>"; };
@@ -76,6 +79,7 @@
C9C73EA324FC471E00EF9516 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
C9C73EA524FC471E00EF9516 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C9E1AA38251E94CC00BD52EC /* RiveRuntime.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RiveRuntime.xcodeproj; path = ../RiveRuntime.xcodeproj; sourceTree = "<group>"; };
C9EEA12E25268E48001BB768 /* teeny.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = teeny.riv; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -93,6 +97,7 @@
C9696B0E24FC6FD10041502A /* Assets */ = {
isa = PBXGroup;
children = (
C9EEA12E25268E48001BB768 /* teeny.riv */,
C9A7D7F22523C1D900AFB875 /* sheep.riv */,
C99E2FE6251E8E35009227CA /* bird.riv */,
C99E2FE7251E8E35009227CA /* funtime.riv */,
@@ -105,14 +110,6 @@
path = Assets;
sourceTree = "<group>";
};
C9696B1324FC71B80041502A /* Helpers */ = {
isa = PBXGroup;
children = (
C9696B1424FC71CE0041502A /* Utilities.swift */,
);
path = Helpers;
sourceTree = "<group>";
};
C9C73E8B24FC471E00EF9516 = {
isa = PBXGroup;
children = (
@@ -135,13 +132,14 @@
C9C73E9624FC471E00EF9516 /* Source */ = {
isa = PBXGroup;
children = (
C9696B1324FC71B80041502A /* Helpers */,
C9C73E9B24FC471E00EF9516 /* ContentView.swift */,
C9C1DF7E252BA5EF00B0A444 /* MyRiveView.swift */,
C9C1DF82252BA62800B0A444 /* MyRiveViewController.swift */,
C9C73E9724FC471E00EF9516 /* AppDelegate.swift */,
C9C73E9924FC471E00EF9516 /* SceneDelegate.swift */,
C9C73E9B24FC471E00EF9516 /* ContentView.swift */,
C9C73E9D24FC471E00EF9516 /* Assets.xcassets */,
C9C73EA224FC471E00EF9516 /* LaunchScreen.storyboard */,
C9C73EA524FC471E00EF9516 /* Info.plist */,
C9C73E9D24FC471E00EF9516 /* Assets.xcassets */,
C9C73E9F24FC471E00EF9516 /* Preview Content */,
);
path = Source;
@@ -258,6 +256,7 @@
C9696B1224FC704A0041502A /* juice.riv in Resources */,
C9C73EA424FC471E00EF9516 /* LaunchScreen.storyboard in Resources */,
C99E2FE3251E8DB4009227CA /* van.riv in Resources */,
C9EEA13125268E48001BB768 /* teeny.riv in Resources */,
C99E2FE8251E8E35009227CA /* bird.riv in Resources */,
C9C73EA124FC471E00EF9516 /* Preview Assets.xcassets in Resources */,
C970484A250822F300CB3AB3 /* simple.riv in Resources */,
@@ -276,7 +275,8 @@
files = (
C9C73E9824FC471E00EF9516 /* AppDelegate.swift in Sources */,
C9C73E9A24FC471E00EF9516 /* SceneDelegate.swift in Sources */,
C9696B1524FC71CE0041502A /* Utilities.swift in Sources */,
C9C1DF7F252BA5EF00B0A444 /* MyRiveView.swift in Sources */,
C9C1DF83252BA62800B0A444 /* MyRiveViewController.swift in Sources */,
C9C73E9C24FC471E00EF9516 /* ContentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@@ -16,9 +16,17 @@ struct ContentView: View {
}
struct MyRive: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> RiveViewController {
return RiveViewController(resource: "truck", withExtension: "riv")
func makeUIViewController(context: Context) -> MyRiveViewController {
return MyRiveViewController(withResource: "truck", withExtension: "riv")
}
func updateUIViewController(_ uiViewController: RiveViewController, context: Context) {}
func updateUIViewController(_ uiViewController: MyRiveViewController, context: Context) {}
}
//struct MyRive: UIViewControllerRepresentable {
// func makeUIViewController(context: Context) -> RiveViewController {
// return RiveViewController(resource: "teeny", withExtension: "riv")
// }
//
// func updateUIViewController(_ uiViewController: RiveViewController, context: Context) {}
//}

View File

@@ -1,31 +0,0 @@
//
// Utilities.swift
// RiveExample
//
// Created by Matt Sullivan on 8/30/20.
// Copyright © 2020 Rive. All rights reserved.
//
import Foundation
func loadBytesFromFile(forResource res: String, withExtension ext: String) -> Data?
{
guard let fileURL = Bundle.main.url(forResource: res, withExtension: ext) else {
print("Failed to create URL for file.")
return nil
}
do {
let data = try Data(contentsOf: fileURL)
return data
}
catch {
print("Error opening file: \(error)")
return nil
}
}
extension Data {
var bytes : [UInt8]{
return [UInt8](self)
}
}

View File

@@ -0,0 +1,28 @@
//
// MyViewView.swift
// RiveExample
//
// Created by Matt Sullivan on 10/5/20.
// Copyright © 2020 Rive. All rights reserved.
//
import UIKit
import RiveRuntime
class MyRiveView: UIView {
var artboard: RiveArtboard?;
func updateArtboard(_ artboard: RiveArtboard) {
self.artboard = artboard;
}
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext(), let artboard = self.artboard else {
return
}
let renderer = RiveRenderer(context: context);
renderer.align(with: rect, withContentRect: artboard.bounds(), with: Alignment.Center, with: Fit.Contain)
artboard.draw(renderer)
}
}

View File

@@ -0,0 +1,122 @@
//
// MyRiveViewController.swift
// RiveExample
//
// Created by Matt Sullivan on 10/5/20.
// Copyright © 2020 Rive. All rights reserved.
//
import UIKit
import RiveRuntime
class MyRiveViewController: UIViewController {
var resourceName: String?
var resourceExt: String?
var artboard: RiveArtboard?
var instance: RiveLinearAnimationInstance?
var displayLink: CADisplayLink?
var lastTime: CFTimeInterval = 0
init(withResource name: String, withExtension: String) {
resourceName = name
resourceExt = withExtension
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
startRive()
}
override func loadView() {
// Wire up an instance of MyRiveView to the controller
let view = MyRiveView()
view.backgroundColor = UIColor.blue
self.view = view
}
func startRive() {
guard let name = resourceName, let ext = resourceExt else {
fatalError("No resource or extension name specified")
}
guard let url = Bundle.main.url(forResource: name, withExtension: ext) else {
fatalError("Failed to locate \(name) in bundle.")
}
guard var data = try? Data(contentsOf: url) else {
fatalError("Failed to load \(url) from bundle.")
}
// Import the data into a RiveFile
let riveFile = RiveFile()
let bytes = [UInt8](data)
data.withUnsafeMutableBytes {(mutableBytes: UnsafeMutablePointer<UInt8>) in
let importResult = RiveFile.import(mutableBytes, bytesLength: UInt64(bytes.count), to: riveFile)
if (importResult != ImportResult.success) {
fatalError("Failed to import \(url).")
}
let artboard = riveFile.artboard()
self.artboard = artboard
// update the artboard in the view
(self.view as! MyRiveView).updateArtboard(artboard)
if (artboard.animationCount() == 0) {
fatalError("No animations in the file.")
}
// Fetch the animation and draw a first frame
let animation = artboard.animation(at: 0)
let instance = animation.instance()
self.instance = instance
instance.advance(by: 0)
instance.apply(to: artboard)
artboard.advance(by: 0)
// Run the looping timer
runTimer()
}
}
// Starts the animation timer
func runTimer() {
displayLink = CADisplayLink(target: self, selector: #selector(tick));
displayLink?.add(to: .main, forMode: .default)
}
// Stops the animation timer
func stopTimer() {
displayLink?.remove(from: .main, forMode: .default)
}
// Animates a frame
@objc func tick() {
guard let displayLink = displayLink, let artboard = artboard else {
// Something's gone wrong, clean up and bug out
stopTimer()
return
}
let timestamp = displayLink.timestamp
// last time needs to be set on the first tick
if (lastTime == 0) {
lastTime = timestamp
}
// Calculate the time elapsed between ticks
let elapsedTime = timestamp - lastTime;
lastTime = timestamp;
// Advance the animation instance and the artboard
instance?.advance(by: elapsedTime) // advance the animation
instance?.apply(to: artboard) // apply to the artboard
artboard.advance(by: elapsedTime) // advance the artboard
// Trigger a redraw
self.view.setNeedsDisplay()
}
}