如何将React Native组件传递至iOS原生(Objective-C)?
React Native View 传递到iOS原生端的实现方案
首先明确:可以实现,但不能直接把RN的View对象跨桥传递——因为RN与原生的桥接仅支持序列化数据。标准做法是通过RN视图的React Tag(原生端用来标识视图的唯一ID),在原生端获取对应的UIView实例。
你现有代码的问题
- 类名不匹配:
.h文件定义的是CustomComponentManager,但.m里写的是CustomViewController,会导致RN无法正确识别模块 - 重复初始化Bridge:在
addReactNativeComponent里新建RCTBridge是错误的,应该复用RN已有的Bridge实例 - 逻辑方向颠倒:你当前代码是在原生端添加RN组件,而需求是把RN端的View传递给原生端
正确实现步骤及代码修改
1. iOS原生端修改(Objective-C)
修正类名,实现可接收React Tag的原生模块:
CustomComponentManager.h
// CustomComponentManager.h #import <React/RCTViewManager.h> #import <React/RCTBridgeModule.h> @interface CustomComponentManager : RCTViewManager <RCTBridgeModule> @end
CustomComponentManager.m
// CustomComponentManager.m #import "CustomComponentManager.h" #import <React/RCTUIManager.h> #import <React/RCTView.h> @implementation CustomComponentManager // 导出模块,RN端通过NativeModules.CustomComponentManager访问 RCT_EXPORT_MODULE() // 导出接收React Tag的方法 RCT_EXPORT_METHOD(receiveReactView:(nonnull NSNumber *)reactViewTag) { // UI操作必须在主线程执行 dispatch_async(dispatch_get_main_queue(), ^{ // 通过RN的UIManager,根据Tag获取对应的原生UIView实例 RCTUIManager *uiManager = [self.bridge uiManager]; [uiManager viewForReactTag:reactViewTag completion:^(UIView *view) { if (view) { // 成功获取到RN传递的View实例,这里可以做任意原生操作 NSLog(@"获取RN View实例成功: %@", view); // 示例:将该View添加到原生根控制器的视图中 UIViewController *rootVC = self.bridge.rootViewController; // 调整位置和尺寸(可根据需求修改) view.frame = CGRectMake(50, 50, view.frame.size.width, view.frame.size.height); [rootVC.view addSubview:view]; } else { NSLog(@"无法获取RN View实例"); } }]; }); } @end
2. React Native端修改(TSX)
通过findNodeHandle获取View的React Tag,传递给原生模块:
App.tsx
// App.tsx import React, { useEffect, useRef } from 'react'; import { LogBox, SafeAreaView, Text, View, NativeModules, findNodeHandle, requireNativeComponent, } from 'react-native'; LogBox.ignoreLogs(['new NativeEventEmitter']); LogBox.ignoreAllLogs(); // 引入原生自定义组件 const CustomComponent = requireNativeComponent('CustomComponent'); // 引入原生模块 const { CustomComponentManager } = NativeModules; const App = () => { // 创建Ref,用于获取CustomComponent的RN实例 const customViewRef = useRef(null); useEffect(() => { if (customViewRef.current) { // 获取当前RN组件对应的原生React Tag const reactViewTag = findNodeHandle(customViewRef.current); if (reactViewTag) { // 调用原生方法,传递Tag CustomComponentManager.receiveReactView(reactViewTag); } } }, []); return ( <SafeAreaView style={{ flex: 1 }}> <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>React Native Pip</Text> {/* 给自定义组件添加Ref,用于获取Tag */} <CustomComponent ref={customViewRef} style={{ width: 200, height: 200, backgroundColor: 'coral' }} /> </View> </SafeAreaView> ); }; export default App;
关键说明
- React Tag是RN内部给每个原生视图分配的唯一ID,是跨桥传递视图引用的标准方式
- 所有UI相关操作必须在主线程执行,所以原生代码里用了
dispatch_async(dispatch_get_main_queue(), ^{...}) - 复用RN已有的Bridge实例,避免重复初始化导致的资源浪费和状态冲突
内容的提问来源于stack exchange,提问作者DhvaniChavda-impero
相关产品推荐
相关产品推荐

