Reference version

This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

RNHostView

一个使 React Native 视图可嵌入 SwiftUI 的组件。

iOS
tvOS
Included in Expo Go
Recommended version:
~57.0.0

一个组件,用于在 React Native 视图渲染到 SwiftUI 组件内部时启用正确的布局行为。它通过更新 shadow node 的大小,将 SwiftUI 的布局信息同步回 React Native 的 Yoga 布局系统。

当 React Native 视图放置在类似 BottomSheetPopoverHStack 等 SwiftUI 组件中时,布局系统需要进行通信。RNHostView 架起了这座桥梁:

  • 使用 matchContents:shadow node 的大小会设置为匹配子 React Native 视图的固有大小,从而允许 SwiftUI 父视图根据 React Native 内容来确定自身大小。
  • 不使用 matchContents:shadow node 的大小会设置为匹配父 SwiftUI 视图的大小,从而允许 React Native 内容填充可用空间(对 flex: 1 布局很有用)。

安装

Terminal
npx expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

用法

结合 matchContents 的基本用法

当你希望 SwiftUI 父容器根据 React Native 内容自动调整自身大小时,请使用 matchContents

RNHostView 与 matchContents
import { useState } from 'react'; import { Pressable, Text, View } from 'react-native'; import { Host, BottomSheet, Button, RNHostView } from '@expo/ui/swift-ui'; function Example() { const [isPresented, setIsPresented] = useState(false); return ( <Host style={{ flex: 1 }}> <Button label="打开面板" onPress={() => setIsPresented(true)} /> <BottomSheet isPresented={isPresented} onIsPresentedChange={setIsPresented}> <RNHostView matchContents> <View style={{ padding: 24 }}> <Text style={{ fontSize: 18, fontWeight: 'bold' }}>React Native 内容</Text> <Pressable style={{ backgroundColor: '#007AFF', padding: 12, borderRadius: 8, marginTop: 16 }} onPress={() => setIsPresented(false)}> <Text style={{ color: 'white', textAlign: 'center' }}>关闭</Text> </Pressable> </View> </RNHostView> </BottomSheet> </Host> ); }

不使用 matchContents 的灵活内容

当你的 React Native 内容中使用 flex: 1 时,请省略 matchContents 属性,这样内容就会填满可用的 SwiftUI 空间。

RNHostView 与 flex 内容
import { useState } from 'react'; import { Text, View } from 'react-native'; import { Host, BottomSheet, Button, Group, RNHostView } from '@expo/ui/swift-ui'; import { presentationDetents } from '@expo/ui/swift-ui/modifiers'; function Example() { const [isPresented, setIsPresented] = useState(false); return ( <Host style={{ flex: 1 }}> <Button label="打开面板" onPress={() => setIsPresented(true)} /> <BottomSheet isPresented={isPresented} onIsPresentedChange={setIsPresented}> <Group modifiers={[presentationDetents(['medium', 'large'])]}> <RNHostView> <View style={{ flex: 1, backgroundColor: '#007AFF', padding: 24 }}> <Text style={{ color: 'white', fontSize: 18 }}> 此内容会填满可用空间 </Text> </View> </RNHostView> </Group> </BottomSheet> </Host> ); }

在 Popover 中使用

RNHostViewPopover 中也能很好地工作,可用于展示可交互的 React Native 内容。

在 Popover 中使用 RNHostView
import { useState } from 'react'; import { Pressable, Text, View } from 'react-native'; import { Host, Button, Popover, RNHostView } from '@expo/ui/swift-ui'; function Example() { const [isPresented, setIsPresented] = useState(false); const [counter, setCounter] = useState(0); return ( <Host style={{ flex: 1 }}> <Popover isPresented={isPresented} onIsPresentedChange={setIsPresented}> <Popover.Trigger> <Button onPress={() => setIsPresented(true)} label="显示弹出框" /> </Popover.Trigger> <Popover.Content> <RNHostView matchContents> <View style={{ padding: 24 }}> <Text style={{ fontSize: 16, fontWeight: 'bold', marginBottom: 8 }}> React Native 内容 </Text> <Text style={{ color: '#666', marginBottom: 12 }}>计数器:{counter}</Text> <Pressable style={{ backgroundColor: '#007AFF', padding: 12, borderRadius: 8, alignItems: 'center', }} onPress={() => setCounter(counter + 1)}> <Text style={{ color: 'white', fontWeight: '600' }}>增加</Text> </Pressable> </View> </RNHostView> </Popover.Content> </Popover> </Host> ); }

API

import { RNHostView } from '@expo/ui/swift-ui';

Component

RNHostView

iOS
tvOS

Type: React.Element<RNHostViewProps>

RNHostViewProps

children

iOS
tvOS
Type: ReactElement

The RN View to be hosted.

matchContents

iOS
tvOS
Optional • Type: boolean • Default: false

When true, the RNHost will update its size in the React Native view tree to match the children's size. When false, the RNHost will use the size of the parent SwiftUI View. Can be only set once on mount.