Reference version

宿主

一个 SwiftUI Host 组件,用于在 React Native 中启用 SwiftUI 组件。

iOS
tvOS
Included in Expo Go
Bundled version:
~56.0.6

For the complete documentation index, see llms.txt. Use this file to discover all available pages.

如需跨平台使用,请参阅通用的 Host ——它会根据平台渲染相应的原生组件。

一个组件,允许你在 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

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

使用

匹配内容尺寸

使用 matchContentsHost 自动调整自身大小以适配其 SwiftUI 内容,而不是要求显式指定尺寸。

注意: matchContents 仅适用于具有固有尺寸或显式 frame 的组件(例如 ButtonToggleText)。像 Slider 和线性 ProgressView 这类可伸缩宽度组件会扩展以填满可用空间,并且没有固有宽度,对它们使用 matchContents 会导致宽度接近于零。对于这些组件,要么在组件上应用 frame 修饰符以给它一个显式宽度,要么改为在 Host 上使用 style 进行显式尺寸设置(例如 style={{ flex: 1 }}style={{ width: 300 }})。

MatchContentsExample.tsx
import { Button, Host } from '@expo/ui/swift-ui'; export default function MatchContentsExample() { return ( <Host matchContents> <Button onPress={() => { console.log('已按下'); }}> 点击 </Button> </Host> ); }

注意: 不要在与滚动容器(ScrollViewListFormLazyHStackLazyVStack)相同的轴上使用 matchContentsmatchContents 会映射为 SwiftUI 的 .fixedSize,这会使滚动容器按其内容大小布局。它还会导致视口之外没有可滚动的内容,因此滚动会悄无声息地停止工作。请使用 matchContents={{ vertical: true }} 并配合 style={{ width: '100%' }}(或在滚动轴上任意有限宽度)。

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 显式设置尺寸

使用 styleHost 设置显式尺寸,例如使用 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('已按下'); }}> 点击 </Button> </VStack> </Host> ); }

忽略键盘安全区域

当 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="输入文本" multiline /> </Host> </KeyboardStickyView> </View> </KeyboardProvider> ); }

忽略所有安全区域

当你希望 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>此内容会延伸到状态栏和 Home 指示条后方。</Text> </VStack> </Host> ); }

接口

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: React.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. Can only be set once on mount.

  • 'all'- ignores all safe area insets.
  • 'keyboard' - ignores only the keyboard safe area.

Acceptable values are: '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.

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.