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.

主机

一个 SwiftUI 宿主组件,可在 React Native 中启用 SwiftUI 组件。

iOS
tvOS
Included in Expo Go
Recommended version:
~57.0.18

一个组件,允许你在 React Native 中放置其他 @expo/ui/swift-ui 组件。它的作用类似于 DOM 中的 <svg>,类似于 react-native-skia 中的 <Canvas>,其底层使用 UIHostingController 在 UIKit 中渲染 SwiftUI 视图。

由于 Host 组件是一个 React Native View,你可以向它传递 style 属性,或者传递 matchContents 属性,使 Host 组件的大小与内容大小匹配。

安装

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 让 Host 自动调整自身大小以适配其 SwiftUI 内容,而不是要求显式指定尺寸。

MatchContentsExample.tsx
import { Button, Host } from '@expo/ui/swift-ui'; export default function MatchContentsExample() { return ( <Host matchContents> <Button onPress={() => { console.log('Pressed'); }} label="Click" /> </Host> ); }
ScrollViewMatchContents.tsx
import { Host, HStack, ScrollView, Text } from '@expo/ui/swift-ui'; export default function ScrollViewMatchContents() { return ( <Host matchContents={{ vertical: true }} style={{ width: '100%' }}> <ScrollView axes="horizontal"> <HStack spacing={12}> {Array.from({ length: 20 }).map((_, i) => ( <Text key={i}>项目 {i}</Text> ))} </HStack> </ScrollView> </Host> ); }

使用 style 显式设置尺寸

使用 style 为 Host 设置显式尺寸,例如通过 flex: 1 填充可用空间。

ExplicitSizingExample.tsx
import { Button, Host, VStack, Text } from '@expo/ui/swift-ui'; export default function ExplicitSizingExample() { return ( <Host style={{ flex: 1 }}> <VStack spacing={8}> <Text>你好,世界!</Text> <Button onPress={() => { console.log('Pressed'); }} label="Click" /> </VStack> </Host> ); }

在 React Native 视图中放置组件

Host 使用 SwiftUI 渲染其子组件。Host 内部的 React Native 视图(例如 View 或 ScrollView)会切换回 React Native 渲染。要在该视图中使用 SwiftUI 组件,请将该组件包装在一个新的 Host 中。即使树中更高层级的 Host 已经包装了该视图,也需要这样做。

ReactNativeLayoutExample.tsx
import { useState } from 'react'; import { ScrollView, Text, View } from 'react-native'; import { Host, Toggle } from '@expo/ui/swift-ui'; export default function ReactNativeLayoutExample() { const [isOn, setIsOn] = useState(false); return ( <ScrollView> <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', padding: 16, }}> <Text>通知</Text> <Host matchContents> <Toggle isOn={isOn} onIsOnChange={setIsOn} /> </Host> </View> </ScrollView> ); }

要在 SwiftUI 组件中放置 React Native 视图,请使用 RNHostView。

忽略键盘安全区域

当 React Native 已经在处理键盘避让时(例如使用 react-native-keyboard-controller),使用 ignoreSafeArea="keyboard" 以防止 SwiftUI 宿主应用自己的键盘内边距。

IgnoreKeyboardExample.tsx
import { Host, TextField } from '@expo/ui/swift-ui'; import { KeyboardProvider, KeyboardStickyView, } from 'react-native-keyboard-controller'; import { View } from 'react-native'; export default function IgnoreKeyboardExample() { return ( <KeyboardProvider> <View style={{ flex: 1, backgroundColor: 'black' }}> <KeyboardStickyView style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: 16, backgroundColor: 'green', }}> <Host matchContents ignoreSafeArea="keyboard" style={{ backgroundColor: 'red' }}> <TextField placeholder="输入文本" axis="vertical" /> </Host> </KeyboardStickyView> </View> </KeyboardProvider> ); }

忽略容器安全区域

使用 ignoreSafeArea="container" 仅移除容器安全区域(刘海、Home 指示器、状态栏和导航栏)。键盘安全区域仍然生效。

IgnoreContainerSafeAreaExample.tsx
import { Button, Host, HStack, Spacer } from '@expo/ui/swift-ui'; import { labelStyle } from '@expo/ui/swift-ui/modifiers'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; export default function IgnoreContainerSafeAreaExample() { const insets = useSafeAreaInsets(); return ( <Host style={{ width: '100%', paddingTop: insets.top }} matchContents={{ vertical: true }} ignoreSafeArea="container"> <HStack> <Button systemImage="chevron.backward" label="Back" modifiers={[labelStyle('iconOnly')]} /> <Spacer /> <Button systemImage="square.and.arrow.up" label="Share" modifiers={[labelStyle('iconOnly')]} /> </HStack> </Host> ); }

忽略所有安全区域

当你希望 SwiftUI 内容延伸到状态栏和键盘后方时,使用 ignoreSafeArea="all",这对于全屏覆盖层或背景非常有用。

IgnoreAllSafeAreasExample.tsx
import { Host, Text, VStack } from '@expo/ui/swift-ui'; export default function IgnoreAllSafeAreasExample() { return ( <Host ignoreSafeArea="all" style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, }}> <VStack> <Text> 此内容延伸到状态栏和主屏幕指示器后方。 </Text> </VStack> </Host> ); }

API

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

Component

Host

iOS
tvOS

Type: React.Element<HostProps>

A hosting component for SwiftUI views.

HostProps

children

iOS
tvOS
Type: ReactNode

colorScheme

iOS
tvOS
Optional • Literal type: string

The color scheme of the host view.

Acceptable values are: 'light' | 'dark'

ignoreSafeArea

iOS
tvOS
Optional • Literal type: string

Controls which safe area regions the SwiftUI hosting view should ignore.

  • 'all' - ignores all safe area insets, including the keyboard.
  • 'container' - ignores only the container safe area (notch, home indicator, status and navigation bars). The keyboard safe area still applies.
  • 'keyboard' - ignores only the keyboard safe area.

Acceptable values are: 'container' | 'all' | 'keyboard'

layoutDirection

iOS
tvOS
Optional • Literal type: string

The layout direction for the SwiftUI content. Defaults to the current locale direction from I18nManager.

Acceptable values are: 'leftToRight' | 'rightToLeft'

matchContents

iOS
tvOS
Optional • Literal type: union • Default: false

When true, the host view will update its size in the React Native view tree to match the content's layout from SwiftUI. Can be only set once on mount.

Acceptable values are: boolean | { horizontal: boolean, vertical: boolean }

onLayoutContent

iOS
tvOS
Optional • Type: (event: { nativeEvent: { height: number, width: number } }) => void

Callback function that is triggered when the SwiftUI content completes its layout. Provides the current dimensions of the content, which may change as the content updates.

pointerEvents

iOS
tvOS
Optional • Literal type: string

Acceptable values are: 'auto' | 'box-none' | 'none' | 'box-only'

seedColor

iOS
tvOS
Optional • Type: ColorValue

Seed color applied to the SwiftUI content as its tint. It propagates through the SwiftUI environment to theme interactive elements (buttons, switches, sliders, and similar controls) rendered by the children.

style

iOS
tvOS
Optional • Type: StyleProp<ViewStyle>

useViewportSizeMeasurement

iOS
tvOS
Optional • Type: boolean • Default: false

When true and no explicit size is provided, the host will use the viewport size as the proposed size for SwiftUI layout. This is particularly useful for SwiftUI views that need to fill their available space, such as Form.