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

一个可在 SwiftUI 中显示 React Native 视图的组件。

iOS
tvOS
Included in Expo Go
Recommended version:
~58.0.1

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

当 React Native 视图放置在 BottomSheet、Popover 或 HStack 等 SwiftUI 组件中时,布局系统需要相互通信。RNHostView 可以弥合这一差距:

  • 使用 matchContents 时:将 shadow node 大小设置为与子 React Native 视图的固有大小一致,让 SwiftUI 父视图根据 React Native 内容调整自身大小。
  • 不使用 matchContents 时:将 shadow node 大小设置为与 SwiftUI 父视图的大小一致,让 React Native 内容填充可用空间(适用于 flex: 1 布局)。

安装

Terminal
- npx expo install @expo/ui
- yarn expo install @expo/ui
- pnpm expo install @expo/ui
- bun 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 with 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="Open sheet" onPress={() => setIsPresented(true)} /> <BottomSheet isPresented={isPresented} onIsPresentedChange={setIsPresented}> <RNHostView matchContents> <View style={{ padding: 24 }}> <Text style={{ fontSize: 18, fontWeight: 'bold' }}> React Native Content </Text> <Pressable style={{ backgroundColor: '#007AFF', padding: 12, borderRadius: 8, marginTop: 16, }} onPress={() => setIsPresented(false)}> <Text style={{ color: 'white', textAlign: 'center' }}> Close </Text> </Pressable> </View> </RNHostView> </BottomSheet> </Host> ); }

不使用 matchContents 的灵活内容

在 React Native 内容中使用 flex: 1 时,请省略 matchContents 属性,以便内容填充可用的 SwiftUI 空间。

RNHostView with flex content
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="Open sheet" 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 }}> This content fills the available space </Text> </View> </RNHostView> </Group> </BottomSheet> </Host> ); }

在 Popover 中使用

RNHostView 非常适合在 Popover 中显示交互式 React Native 内容。

RNHostView in Popover
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="Show Popover" /> </Popover.Trigger> <Popover.Content> <RNHostView matchContents> <View style={{ padding: 24 }}> <Text style={{ fontSize: 16, fontWeight: 'bold', marginBottom: 8, }}> React Native Content </Text> <Text style={{ color: '#666', marginBottom: 12 }}> Counter: {counter} </Text> <Pressable style={{ backgroundColor: '#007AFF', padding: 12, borderRadius: 8, alignItems: 'center', }} onPress={() => setCounter(counter + 1)}> <Text style={{ color: 'white', fontWeight: '600' }}> Increment </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.

onLayout

iOS
tvOS
Optional • Type: (event: LayoutChangeEvent) => void