Skip to content

Commit

Permalink
feat: add support for setTextRunValueAtPath
Browse files Browse the repository at this point in the history
  • Loading branch information
0x100101 authored and HayesGordon committed Nov 28, 2024
1 parent 21b96a3 commit c899dbf
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,14 @@ class RiveReactNativeView(private val context: ThemedReactContext) : FrameLayout
}
}

fun setTextRunValueAtPath(textRunName: String, textValue: String, path: String) {
try {
riveAnimationView.controller.activeArtboard?.textRun(textRunName, path)?.text = textValue
} catch (ex: RiveException) {
handleRiveException(ex)
}
}

fun update() {
reloadIfNeeded()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ class RiveReactNativeViewManager : SimpleViewManager<RiveReactNativeView>() {
}
}

"setTextRunValueAtPath" -> {
args?.let {
val textRunName: String = it.getString(0)
val textValue: String = it.getString(1)
val path: String = it.getString(2)
view.run {
this.setTextRunValueAtPath(textRunName, textValue, path)
}
}
}

// Other

else -> { }
Expand Down
Binary file not shown.
Binary file added example/ios/Assets/hello_world_nested.riv
Binary file not shown.
10 changes: 10 additions & 0 deletions example/ios/RiveReactNativeExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2DCD954D1E0B4F2C00145EB5 /* RiveReactNativeExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RiveReactNativeExampleTests.m */; };
372D10362CEC2851008B4896 /* hello_world_nested.riv in Resources */ = {isa = PBXBuildFile; fileRef = 372D10352CEC2851008B4896 /* hello_world_nested.riv */; };
372D10372CEC2851008B4896 /* hello_world_nested.riv in Resources */ = {isa = PBXBuildFile; fileRef = 372D10352CEC2851008B4896 /* hello_world_nested.riv */; };
372D10382CEC2851008B4896 /* hello_world_nested.riv in Resources */ = {isa = PBXBuildFile; fileRef = 372D10352CEC2851008B4896 /* hello_world_nested.riv */; };
372D10392CEC2851008B4896 /* hello_world_nested.riv in Resources */ = {isa = PBXBuildFile; fileRef = 372D10352CEC2851008B4896 /* hello_world_nested.riv */; };
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 */; };
Expand Down Expand Up @@ -75,6 +79,7 @@
2D02E4901E0B4A5D006451C7 /* RiveReactNativeExample-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RiveReactNativeExample-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
314745779119439EA32E37A2 /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = "<group>"; };
317641388F0F49BFB3014F25 /* FontAwesome5_Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome5_Regular.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome5_Regular.ttf"; sourceTree = "<group>"; };
372D10352CEC2851008B4896 /* hello_world_nested.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = hello_world_nested.riv; sourceTree = "<group>"; };
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 = "<group>"; };
651168751AA54B47B3B831AF /* FontAwesome.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = "<group>"; };
7038BFFCA6554E2ABBA220DE /* AntDesign.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = AntDesign.ttf; path = "../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -273,6 +278,7 @@
9D879D0826578A5400D01424 /* loopy.riv */,
9D879CFF265642BA00D01424 /* truck_v7.riv */,
9D4FE6112649427F0098BF6A /* bird.riv */,
372D10352CEC2851008B4896 /* hello_world_nested.riv */,
);
path = Assets;
sourceTree = "<group>";
Expand Down Expand Up @@ -410,6 +416,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
372D10392CEC2851008B4896 /* hello_world_nested.riv in Resources */,
F8AA4CA52C0F3FDB00C1A5FF /* runtime_nested_inputs.riv in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -424,6 +431,7 @@
9D879D0B26578A5E00D01424 /* artboard_animations.riv in Resources */,
F8AA4CA42C0F3FDB00C1A5FF /* runtime_nested_inputs.riv in Resources */,
E5637D7A292BD27F000CBC1E /* skills_listener.riv in Resources */,
372D10382CEC2851008B4896 /* hello_world_nested.riv in Resources */,
9EBE42F22CDD459200014668 /* layout_test.riv in Resources */,
04A886F326A990050078530A /* two_bone_ik.riv in Resources */,
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
Expand All @@ -444,6 +452,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
372D10372CEC2851008B4896 /* hello_world_nested.riv in Resources */,
2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -452,6 +461,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
372D10362CEC2851008B4896 /* hello_world_nested.riv in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
5 changes: 5 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ErrorNotHandled from './ErrorNotHandled';
import ErrorHandledManually from './ErrorHandledManually';
import MeshExample from './MeshExample';
import DynamicText from './DynamicText';
import NestedDynamicText from './NestedDynamicText';
import NestedInputs from './NestedInputs';
import Events from './Events';

Expand Down Expand Up @@ -65,6 +66,10 @@ function App() {
<Stack.Screen name="Events" component={Events} />
<Stack.Screen name="NestedInputs" component={NestedInputs} />
<Stack.Screen name="DynamicText" component={DynamicText} />
<Stack.Screen
name="NestedDynamicText"
component={NestedDynamicText}
/>
<Stack.Screen
name="MultipleArtboards"
component={MultipleArtboards}
Expand Down
8 changes: 8 additions & 0 deletions example/src/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ export default function Home({ navigation }) {
Dynamic Text
</Button>

<Button
mode="contained"
onPress={() => navigation.navigate('NestedDynamicText')}
style={styles.buttonStyle}
>
Nested Dynamic Text
</Button>

<Button
mode="contained"
onPress={() => navigation.navigate('ErrorNotHandled')}
Expand Down
71 changes: 71 additions & 0 deletions example/src/NestedDynamicText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import * as React from 'react';
import { useRef } from 'react';

import { SafeAreaView, ScrollView, StyleSheet } from 'react-native';
import { TextInput } from 'react-native-gesture-handler';
import Rive, {
Alignment,
Fit,
RNRiveError,
RNRiveErrorType,
RiveRef,
} from 'rive-react-native';

export default function NestedDynamicText() {
const riveRef = useRef<RiveRef>(null);

const handleInputChange = (e: string) => {
// Set the TextRun value of the 'name' TextRun
// The name must exist else an error will be thrown
// See: https://help.rive.app/runtimes/text
riveRef.current?.setTextRunValue('Run A', e);
// Set the TextRun value of the 'Run B' TextRun in nested Artboard 2.
riveRef.current?.setTextRunValueAtPath('Run B', e, 'Artboard 2');
};

return (
<SafeAreaView style={styles.safeAreaViewContainer}>
<ScrollView>
<Rive
ref={riveRef}
fit={Fit.Contain}
alignment={Alignment.Center}
style={styles.animation}
resourceName="hello_world_nested"
onError={(riveError: RNRiveError) => {
switch (riveError.type) {
case RNRiveErrorType.TextRunNotFoundError: {
console.log(`${riveError.message}`);
return;
}
default:
console.log('Unhandled error');
return;
}
}}
/>
<TextInput
onChangeText={handleInputChange}
defaultValue=""
style={styles.input}
/>
</ScrollView>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
safeAreaViewContainer: {
flex: 1,
},
input: {
height: 40,
margin: 12,
borderWidth: 1,
padding: 10,
},
animation: {
width: '100%',
height: 100,
},
});
10 changes: 9 additions & 1 deletion ios/RiveReactNativeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,15 @@ class RiveReactNativeView: RCTView, RivePlayerDelegate, RiveStateMachineDelegate
handleRiveError(error: error)
}
}


func setTextRunValueAtPath(textRunName: String, textRunValue: String, path: String) throws {
do {
try viewModel?.setTextRunValue(textRunName, path: path, textValue: textRunValue)
} catch let error as NSError {
handleRiveError(error: error)
}
}

// MARK: - StateMachineDelegate

@objc func stateMachine(_ stateMachine: RiveStateMachineInstance, didChangeState stateName: String) {
Expand Down
4 changes: 2 additions & 2 deletions ios/RiveReactNativeViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ @interface RCT_EXTERN_MODULE(RiveReactNativeViewManager, RCTViewManager)
RCT_EXTERN_METHOD(touchMoved:(nonnull NSNumber *)node x:(nonnull NSNumber*)x y:(nonnull NSNumber*)y)
RCT_EXTERN_METHOD(touchEnded:(nonnull NSNumber *)node x:(nonnull NSNumber*)x y:(nonnull NSNumber*)y)
RCT_EXTERN_METHOD(touchCancelled:(nonnull NSNumber *)node x:(nonnull NSNumber*)x y:(nonnull NSNumber*)y)
RCT_EXTERN_METHOD(setTextRunValue:(nonnull NSNumber *)node textRunName:(nonnull NSString)textRunName textRunValue:(nonnull
NSString)textRunValue)
RCT_EXTERN_METHOD(setTextRunValue:(nonnull NSNumber *)node textRunName:(nonnull NSString)textRunName textRunValue:(nonnull NSString)textRunValue)
RCT_EXTERN_METHOD(setTextRunValueAtPath:(nonnull NSNumber *)node textRunName:(nonnull NSString)textRunName textRunValue:(nonnull NSString)textRunValue path:(nonnull NSString)path)
@end

7 changes: 7 additions & 0 deletions ios/RiveReactNativeViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ class RiveReactNativeViewManager: RCTViewManager {
}
}

@objc func setTextRunValueAtPath(_ node: NSNumber, textRunName: String, textRunValue: String, path: String) {
DispatchQueue.main.async {
let view = self.bridge.uiManager.view(forReactTag: node) as! RiveReactNativeView
try! view.setTextRunValueAtPath(textRunName: textRunName, textRunValue: textRunValue, path: path)
}
}

@objc static override func requiresMainQueueSetup() -> Bool {
return false
}
Expand Down
14 changes: 14 additions & 0 deletions src/Rive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,18 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
}
}, []);

const setTextRunValueAtPath = useCallback<
RiveRef[ViewManagerMethod.setTextRunValueAtPath]
>((textRunName: string, textValue: string, path: string) => {
if (textRunName) {
UIManager.dispatchViewManagerCommand(
findNodeHandle(riveRef.current),
ViewManagerMethod.setTextRunValueAtPath,
[textRunName, textValue, path]
);
}
}, []);

useImperativeHandle(
ref,
() => ({
Expand All @@ -386,6 +398,7 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
touchBegan,
touchEnded,
setTextRunValue,
setTextRunValueAtPath,
}),
[
play,
Expand All @@ -399,6 +412,7 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
touchBegan,
touchEnded,
setTextRunValue,
setTextRunValueAtPath,
]
);

Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export type RiveRef = {
touchBegan: (x: number, y: number) => void;
touchEnded: (x: number, y: number) => void;
setTextRunValue: (textRunName: string, value: string) => void;
setTextRunValueAtPath: (
textRunName: string,
value: string,
path: string
) => void;
};

export enum ViewManagerMethod {
Expand All @@ -39,6 +44,7 @@ export enum ViewManagerMethod {
touchBegan = 'touchBegan',
touchEnded = 'touchEnded',
setTextRunValue = 'setTextRunValue',
setTextRunValueAtPath = 'setTextRunValueAtPath',
}

export enum Fit {
Expand Down

0 comments on commit c899dbf

Please sign in to comment.