You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将React Native组件传递至iOS原生(Objective-C)?

React Native View 传递到iOS原生端的实现方案

首先明确:可以实现,但不能直接把RN的View对象跨桥传递——因为RN与原生的桥接仅支持序列化数据。标准做法是通过RN视图的React Tag(原生端用来标识视图的唯一ID),在原生端获取对应的UIView实例。

你现有代码的问题

  1. 类名不匹配:.h文件定义的是CustomComponentManager,但.m里写的是CustomViewController,会导致RN无法正确识别模块
  2. 重复初始化Bridge:在addReactNativeComponent里新建RCTBridge是错误的,应该复用RN已有的Bridge实例
  3. 逻辑方向颠倒:你当前代码是在原生端添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:35:58