Passing events from SwiftUI Button created by RN and getting it back to SwiftUI

This commit is contained in:
Artur Gurgul 2025-08-03 12:07:14 +02:00
parent 41081b5084
commit 1a9884e0e9
6 changed files with 24 additions and 14 deletions

12
App.tsx
View file

@ -1,6 +1,6 @@
import { NewAppScreen } from '@react-native/new-app-screen' import { NewAppScreen } from '@react-native/new-app-screen'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { StatusBar, Text, StyleSheet, useColorScheme, View } from 'react-native' import { StatusBar, Text, StyleSheet, useColorScheme, ScrollView } from 'react-native'
import { NativeEventEmitter, NativeModules } from 'react-native' import { NativeEventEmitter, NativeModules } from 'react-native'
const { Emitter } = NativeModules const { Emitter } = NativeModules
@ -16,12 +16,17 @@ const BaseButton = requireNativeComponent<CustomButtonProps>('BaseButton')
export default function App() { export default function App() {
const isDarkMode = useColorScheme() === 'dark' const isDarkMode = useColorScheme() === 'dark'
const [message, setMessage] = useState(null) const [message, setMessage] = useState(null)
const [color, setColor] = useState("#FFF")
useEffect(() => { useEffect(() => {
const emitter = new NativeEventEmitter(Emitter); const emitter = new NativeEventEmitter(Emitter);
const subscription = emitter.addListener('onMessage', (event) => { const subscription = emitter.addListener('onMessage', (event) => {
if (event?.message) { if (event?.message) {
setMessage(event.message) setMessage(event.message)
if (event?.message == "hello from Swift!") {
setColor("#00F")
}
} }
}) })
@ -31,13 +36,12 @@ export default function App() {
}, []) }, [])
return ( return (
<View style={styles.container}> <ScrollView style={{...styles.container, backgroundColor: color}}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<Text>{message ?? 'Waiting for message...'}</Text> <Text>{message ?? 'Waiting for message...'}</Text>
<CustomButton style={{ height: 200 }} /> <CustomButton style={{ height: 200 }} />
<BaseButton style={{ height: 200 }} /> <BaseButton style={{ height: 200 }} />
<NewAppScreen templateFileName="App.tsx" /> </ScrollView>
</View>
); );
} }

View file

@ -8,9 +8,11 @@
import SwiftUI import SwiftUI
struct BaseButton: View { struct BaseButton: View {
@EnvironmentObject var sharedState: SharedState
var body: some View { var body: some View {
Button("SwiftUI Button") { Button("SwiftUI Button") {
sharedState.text1 = "Clicked in SwiftUI button that was created in RN"
} }
} }
} }

View file

@ -12,7 +12,9 @@ import SwiftUI
@objc(BaseButtonManager) @objc(BaseButtonManager)
class BaseButtonManager: RCTViewManager { class BaseButtonManager: RCTViewManager {
override func view() -> UIView! { override func view() -> UIView! {
return UIHostingController(rootView: BaseButton()).view return UIHostingController(
rootView: BaseButton()
).view
} }
override static func requiresMainQueueSetup() -> Bool { override static func requiresMainQueueSetup() -> Bool {

View file

@ -7,8 +7,6 @@
import Combine import Combine
import React import React
//import React_RCTAppDelegate
//import ReactAppDependencyProvider
@objc(Emitter) @objc(Emitter)
class Emitter: RCTEventEmitter { class Emitter: RCTEventEmitter {
@ -19,7 +17,6 @@ class Emitter: RCTEventEmitter {
override init() { override init() {
super.init() super.init()
EventEmitter.sharedInstance.register(eventEmitter: self) EventEmitter.sharedInstance.register(eventEmitter: self)
} }
override func supportedEvents() -> [String]! { override func supportedEvents() -> [String]! {

View file

@ -15,6 +15,9 @@ final class SharedState: ObservableObject {
var reactNativeFactory: RCTReactNativeFactory? var reactNativeFactory: RCTReactNativeFactory?
private let emitter = EventEmitter.sharedInstance private let emitter = EventEmitter.sharedInstance
// SwiftUI => RN => SwiftUI
@Published var text1: String = ""
func send(message: String) { func send(message: String) {
emitter.send(message: message) emitter.send(message: message)
} }

View file

@ -11,12 +11,14 @@ struct ToolboxHeader: View {
@EnvironmentObject var sharedState: SharedState @EnvironmentObject var sharedState: SharedState
var body: some View { var body: some View {
HStack { VStack {
Text("Actions") HStack {
Button("Make it blue") { Text("Actions")
print("Making it blue") Button("Make it blue") {
sharedState.send(message: "hello from Swift!") sharedState.send(message: "hello from Swift!")
}
} }
Text("SwiftUI => RN => SwiftUI: \(sharedState.text1)")
} }
} }
} }