From 8351e67d7a31902fa3b78303be1787b1c187f7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Krzy=C5=BCowski?= Date: Thu, 20 May 2021 12:52:45 +0200 Subject: [PATCH] feat: added ios simple example (#27) * feat: updated pod source and added example file * feat: added simple ios example --- .../android/app/src/main/res/raw/truck_v7.riv | Bin 0 -> 34258 bytes example/ios/Assets/truck_v7.riv | Bin 0 -> 34258 bytes example/ios/Podfile | 2 +- example/ios/Podfile.lock | 14 +- .../project.pbxproj | 4 + example/src/Simple.tsx | 6 +- example/src/SimpleControls.tsx | 4 +- ios/MyRiveView.swift | 21 -- ios/RiveReactNativeView.swift | 47 +++ ios/RiveReactNativeViewManager.m | 4 +- ios/RiveReactNativeViewManager.swift | 280 +++++++++--------- utility.swift | 23 ++ 12 files changed, 230 insertions(+), 175 deletions(-) create mode 100644 example/android/app/src/main/res/raw/truck_v7.riv create mode 100644 example/ios/Assets/truck_v7.riv delete mode 100644 ios/MyRiveView.swift create mode 100644 ios/RiveReactNativeView.swift create mode 100644 utility.swift diff --git a/example/android/app/src/main/res/raw/truck_v7.riv b/example/android/app/src/main/res/raw/truck_v7.riv new file mode 100644 index 0000000000000000000000000000000000000000..7d8445eb58444af3b578290b69b0da9ae8336872 GIT binary patch literal 34258 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 VFg!}6Iu>Efyb6ZR!FZIh{|D6-QJVk& literal 0 HcmV?d00001 diff --git a/example/ios/Assets/truck_v7.riv b/example/ios/Assets/truck_v7.riv new file mode 100644 index 0000000000000000000000000000000000000000..7d8445eb58444af3b578290b69b0da9ae8336872 GIT binary patch literal 34258 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 VFg!}6Iu>Efyb6ZR!FZIh{|D6-QJVk& literal 0 HcmV?d00001 diff --git a/example/ios/Podfile b/example/ios/Podfile index 350057a..4dcd893 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -9,7 +9,7 @@ target 'RiveReactNativeExample' do use_react_native!(:path => config["reactNativePath"]) pod 'rive-react-native', :path => '../..' - pod 'RiveRuntime', :git => 'https://github.com/callstack-internal/RiveFramework.git' + pod 'RiveRuntime', :git => 'https://github.com/rive-app/test-ios.git' # Enables Flipper. # diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 922c5bc..18dc09b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -310,7 +310,7 @@ PODS: - rive-react-native (0.1.0): - React-Core - RiveRuntime - - RiveRuntime (0.0.5) + - RiveRuntime (0.0.3) - RNCMaskedView (0.1.11): - React - RNCPicker (1.16.0): @@ -401,7 +401,7 @@ DEPENDENCIES: - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - rive-react-native (from `../..`) - - RiveRuntime (from `https://github.com/callstack-internal/RiveFramework.git`) + - RiveRuntime (from `https://github.com/rive-app/test-ios.git`) - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" - "RNCPicker (from `../node_modules/@react-native-picker/picker`)" - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) @@ -480,7 +480,7 @@ EXTERNAL SOURCES: rive-react-native: :path: "../.." RiveRuntime: - :git: https://github.com/callstack-internal/RiveFramework.git + :git: https://github.com/rive-app/test-ios.git RNCMaskedView: :path: "../node_modules/@react-native-community/masked-view" RNCPicker: @@ -496,8 +496,8 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: RiveRuntime: - :commit: cc8984b15746af9f271f4cc59ffa04e48990bcc3 - :git: https://github.com/callstack-internal/RiveFramework.git + :commit: 497da973e950dfc117414a648d477143fa3c89da + :git: https://github.com/rive-app/test-ios.git SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c @@ -538,7 +538,7 @@ SPEC CHECKSUMS: React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b rive-react-native: 78ec9539067d4c4c2201a66ff1de735e67e68f9d - RiveRuntime: 16e3ea7b8e50886eeee9e6f4ce802b603eb97289 + RiveRuntime: caef28465be0ac1d011da7f4519d8349a3930cfe RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489 RNCPicker: 918e98b54a141791e99614b1c320ef2e58300490 RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211 @@ -547,6 +547,6 @@ SPEC CHECKSUMS: Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: decc314aa4ef3fffdebc04395ccc65433a79d821 +PODFILE CHECKSUM: 393a22f7cdc9e51ef63f6fe2cde315006e6d1517 COCOAPODS: 1.10.1 diff --git a/example/ios/RiveReactNativeExample.xcodeproj/project.pbxproj b/example/ios/RiveReactNativeExample.xcodeproj/project.pbxproj index cb0d8da..fbb1ddb 100644 --- a/example/ios/RiveReactNativeExample.xcodeproj/project.pbxproj +++ b/example/ios/RiveReactNativeExample.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 4C39C56BAD484C67AA576FFA /* libPods-RiveReactNativeExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CA3E69C5B9553B26FBA2DF04 /* libPods-RiveReactNativeExample.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 9D4FE6122649427F0098BF6A /* bird.riv in Resources */ = {isa = PBXBuildFile; fileRef = 9D4FE6112649427F0098BF6A /* bird.riv */; }; + 9D879D00265642BA00D01424 /* truck_v7.riv in Resources */ = {isa = PBXBuildFile; fileRef = 9D879CFF265642BA00D01424 /* truck_v7.riv */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -53,6 +54,7 @@ 47F7ED3B7971BE374F7B8635 /* Pods-RiveReactNativeExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiveReactNativeExample.debug.xcconfig"; path = "Target Support Files/Pods-RiveReactNativeExample/Pods-RiveReactNativeExample.debug.xcconfig"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RiveReactNativeExample/LaunchScreen.storyboard; sourceTree = ""; }; 9D4FE6112649427F0098BF6A /* bird.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = bird.riv; sourceTree = ""; }; + 9D879CFF265642BA00D01424 /* truck_v7.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = truck_v7.riv; sourceTree = ""; }; CA3E69C5B9553B26FBA2DF04 /* libPods-RiveReactNativeExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RiveReactNativeExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E00ACF0FDA8BF921659E2F9A /* Pods-RiveReactNativeExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiveReactNativeExample.release.xcconfig"; path = "Target Support Files/Pods-RiveReactNativeExample/Pods-RiveReactNativeExample.release.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; @@ -179,6 +181,7 @@ 9D4FE60A26493B460098BF6A /* Assets */ = { isa = PBXGroup; children = ( + 9D879CFF265642BA00D01424 /* truck_v7.riv */, 9D4FE6112649427F0098BF6A /* bird.riv */, ); path = Assets; @@ -323,6 +326,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9D879D00265642BA00D01424 /* truck_v7.riv in Resources */, 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 9D4FE6122649427F0098BF6A /* bird.riv in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, diff --git a/example/src/Simple.tsx b/example/src/Simple.tsx index 878f0c7..9466009 100644 --- a/example/src/Simple.tsx +++ b/example/src/Simple.tsx @@ -2,11 +2,13 @@ import * as React from 'react'; import { SafeAreaView, StyleSheet, ScrollView } from 'react-native'; import Rive from 'rive-react-native'; +const resourceName = 'truck_v7'; + export default function Simple() { return ( - + ); @@ -20,11 +22,9 @@ const styles = StyleSheet.create({ flexGrow: 1, alignItems: 'center', justifyContent: 'center', - marginBottom: 150, }, animation: { width: '100%', height: 400, - marginVertical: 20, }, }); diff --git a/example/src/SimpleControls.tsx b/example/src/SimpleControls.tsx index d44c90e..b8adc35 100644 --- a/example/src/SimpleControls.tsx +++ b/example/src/SimpleControls.tsx @@ -4,6 +4,8 @@ import { SafeAreaView, StyleSheet, ScrollView, View } from 'react-native'; import Rive, { RiveRef } from 'rive-react-native'; import { Button, Text } from 'react-native-paper'; +const resourceName = 'truck_v7'; + const BUTTONS = ['stop', 'play', 'pause'] as const; type ButtonsKey = typeof BUTTONS[number]; @@ -39,7 +41,7 @@ export default function SimpleControls() { ref={riveRef} style={styles.box} autoplay={false} - resourceName={'flying_car'} + resourceName={resourceName} /> diff --git a/ios/MyRiveView.swift b/ios/MyRiveView.swift deleted file mode 100644 index 530052d..0000000 --- a/ios/MyRiveView.swift +++ /dev/null @@ -1,21 +0,0 @@ -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) - } - -} - diff --git a/ios/RiveReactNativeView.swift b/ios/RiveReactNativeView.swift new file mode 100644 index 0000000..052c848 --- /dev/null +++ b/ios/RiveReactNativeView.swift @@ -0,0 +1,47 @@ +import UIKit +import RiveRuntime + +class RiveReactNativeView: UIView { + @objc var resourceName: String? + let riveView = RiveView() + + override init(frame: CGRect) { + super.init(frame: frame) + riveView.frame = frame + riveView.configure(getRiveFile(resourceName: "truck_v7"), andAutoPlay: false) + addSubview(riveView) + } + + + override func layoutSubviews() { + super.layoutSubviews() + for view in subviews { + view.reactSetFrame(self.bounds) + } + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + fatalError("init(coder:) has not been implemented") + } + + @objc func play() { + riveView.play() + } + + +// 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) +// } + +} + diff --git a/ios/RiveReactNativeViewManager.m b/ios/RiveReactNativeViewManager.m index d764139..fbba065 100644 --- a/ios/RiveReactNativeViewManager.m +++ b/ios/RiveReactNativeViewManager.m @@ -1,11 +1,11 @@ #import "React/RCTBridgeModule.h" -#import "RCTViewManager.h" +#import "React/RCTViewManager.h" @interface RCT_EXTERN_MODULE(RiveReactNativeViewManager, RCTViewManager) RCT_EXPORT_VIEW_PROPERTY(resourceName, NSString) -RCT_EXTERN_METHOD(play:(nonnull NSNumber *)node) +RCT_EXTERN_METHOD(play:(nonnull NSNumber *)node animationNames:(nonnull NSArray *)animationNames loopMode:(NSString)loopMode direction:(NSString)direction areStateMachines:(BOOL)areStateMachines) RCT_EXTERN_METHOD(pause:(nonnull NSNumber *)node) diff --git a/ios/RiveReactNativeViewManager.swift b/ios/RiveReactNativeViewManager.swift index 402c0db..ccbf833 100644 --- a/ios/RiveReactNativeViewManager.swift +++ b/ios/RiveReactNativeViewManager.swift @@ -6,156 +6,156 @@ import RiveRuntime class RiveReactNativeViewManager: RCTViewManager { override func view() -> UIView! { - return ContainerView() + return RiveReactNativeView() } override class func requiresMainQueueSetup() -> Bool { return true } - @objc func play(_ node: NSNumber) { + @objc func play(_ node: NSNumber, animationNames: [String], loopMode: String, direction: String, areStateMachines: Bool) { DispatchQueue.main.async { - let component = self.bridge.uiManager.view(forReactTag: node) as! ContainerView + let component = self.bridge.uiManager.view(forReactTag: node) as! RiveReactNativeView component.play() } } - - @objc func pause(_ node: NSNumber) { - DispatchQueue.main.async { - let component = self.bridge.uiManager.view(forReactTag: node) as! ContainerView - component.pause() - } - } +// +// @objc func pause(_ node: NSNumber) { +// DispatchQueue.main.async { +// let component = self.bridge.uiManager.view(forReactTag: node) as! ContainerView +// component.pause() +// } +// } } -class ContainerView: UIView { - - @objc var resourceName: String? { - didSet { - if let _ = resourceName, !resourceName!.isEmpty { - startRive() - } - } - } - let resourceExt = "riv" - var artboard: RiveArtboard? - var instance: RiveLinearAnimationInstance? - var displayLink: CADisplayLink? - var lastTime: CFTimeInterval = 0 - let rView = MyRiveView() - - override init(frame: CGRect) { - super.init(frame: frame) - setupView() - } - - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - fatalError("init(coder:) has not been implemented") - } - - func setupView() { - self.addSubview(rView) - } - - override func reactSetFrame(_ frame: CGRect) { - super.reactSetFrame(frame) - rView.reactSetFrame(frame) - } - - func startRive() { - guard let name = self.resourceName else { - fatalError("No resource name specified") - } - guard let url = Bundle.main.url(forResource: name, withExtension: resourceExt) 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 bytes = [UInt8](data) - - data.withUnsafeMutableBytes{(riveBytes:UnsafeMutableRawBufferPointer) in - guard let rawPointer = riveBytes.baseAddress else { - fatalError("File pointer is messed up") - } - let pointer = rawPointer.bindMemory(to: UInt8.self, capacity: bytes.count) - - guard let riveFile = RiveFile(bytes:pointer, byteLength: UInt64(bytes.count)) else { - fatalError("Failed to import \(url).") - } - - let artboard = riveFile.artboard() - - self.artboard = artboard - // update the artboard in the view - rView.updateArtboard(artboard) - - if (artboard.animationCount() == 0) { - fatalError("No animations in the file.") - } - - // Fetch an animation - let animation = artboard.animation(at: 0) - self.instance = animation.instance() - - // Advance the artboard, this will ensure the first - // frame is displayed when the artboard is drawn - artboard.advance(by: 0) - - // Start the animation loop - 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 - rView.setNeedsDisplay() - } - - @objc func play() { - runTimer() - } - - @objc func pause() { - stopTimer() - } - - -} +//class ContainerView: UIView { +// +// @objc var resourceName: String? { +// didSet { +// if let _ = resourceName, !resourceName!.isEmpty { +// startRive() +// } +// } +// } +// let resourceExt = "riv" +// var artboard: RiveArtboard? +// var instance: RiveLinearAnimationInstance? +// var displayLink: CADisplayLink? +// var lastTime: CFTimeInterval = 0 +// let rView = MyRiveView() +// +// override init(frame: CGRect) { +// super.init(frame: frame) +// setupView() +// } +// +// required init?(coder aDecoder: NSCoder) { +// super.init(coder: aDecoder) +// fatalError("init(coder:) has not been implemented") +// } +// +// func setupView() { +// self.addSubview(rView) +// } +// +// override func reactSetFrame(_ frame: CGRect) { +// super.reactSetFrame(frame) +// rView.reactSetFrame(frame) +// } +// +// func startRive() { +// guard let name = self.resourceName else { +// fatalError("No resource name specified") +// } +// guard let url = Bundle.main.url(forResource: name, withExtension: resourceExt) 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 bytes = [UInt8](data) +// +// data.withUnsafeMutableBytes{(riveBytes:UnsafeMutableRawBufferPointer) in +// guard let rawPointer = riveBytes.baseAddress else { +// fatalError("File pointer is messed up") +// } +// let pointer = rawPointer.bindMemory(to: UInt8.self, capacity: bytes.count) +// +// guard let riveFile = RiveFile(bytes:pointer, byteLength: UInt64(bytes.count)) else { +// fatalError("Failed to import \(url).") +// } +// +// let artboard = riveFile.artboard() +// +// self.artboard = artboard +// // update the artboard in the view +// rView.updateArtboard(artboard) +// +// if (artboard.animationCount() == 0) { +// fatalError("No animations in the file.") +// } +// +// // Fetch an animation +// let animation = artboard.animation(at: 0) +// self.instance = animation.instance() +// +// // Advance the artboard, this will ensure the first +// // frame is displayed when the artboard is drawn +// artboard.advance(by: 0) +// +// // Start the animation loop +// 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 +// rView.setNeedsDisplay() +// } +// +// @objc func play() { +// runTimer() +// } +// +// @objc func pause() { +// stopTimer() +// } +// +// +//} diff --git a/utility.swift b/utility.swift new file mode 100644 index 0000000..78bda7b --- /dev/null +++ b/utility.swift @@ -0,0 +1,23 @@ +func getRiveFile(resourceName: String, resourceExt: String=".riv") -> RiveFile { + guard let url = Bundle.main.url(forResource: resourceName, withExtension: resourceExt) else { + fatalError("Failed to locate \(resourceName) in bundle.") + } + guard var data = try? Data(contentsOf: url) else { + fatalError("Failed to load \(url) from bundle.") + } + + // Import the data into a RiveFile + let bytes = [UInt8](data) + + return data.withUnsafeMutableBytes{(riveBytes:UnsafeMutableRawBufferPointer)->RiveFile in + guard let rawPointer = riveBytes.baseAddress else { + fatalError("File pointer is messed up") + } + let pointer = rawPointer.bindMemory(to: UInt8.self, capacity: bytes.count) + + guard let riveFile = RiveFile(bytes:pointer, byteLength: UInt64(bytes.count)) else { + fatalError("Failed to import \(url).") + } + return riveFile + } +}