使用 Expo UI 构建 SwiftUI 应用
了解如何使用 Expo UI 将 SwiftUI 集成到你的 Expo 应用中。
信息 在 SDK 54 及更高版本 可用。
Expo UI 将 SwiftUI 引入 React Native。你可以使用现代 SwiftUI 基本组件来构建你的应用。
🌐 Expo UI brings SwiftUI to React Native. You can use modern SwiftUI primitives to build your apps.
本指南介绍了使用 Expo UI 将 SwiftUI 集成到 Expo 应用中的基础知识。
🌐 This guide covers the basics of using Expo UI to integrate SwiftUI into your Expo apps.

了解如何在你的 React Native 应用中使用新的 Expo UI 构建真实的 SwiftUI 视图。
特性
🌐 Features
- SwiftUI 原语:Expo UI 不是另一个 UI 库。它将 SwiftUI 原语引入了 Expo。
- 一对一映射:Expo UI 中的组件与 SwiftUI 视图存在一对一的映射关系。你可以轻松地在 SwiftUI 生态系统中探索可用的视图,例如 探索 SwiftUI 或 Libraried 应用,并找到对应的 Expo UI 组件。
- 全应用支持:Expo UI 设计为可在整个应用中使用。你可以完全使用 Expo UI 编写应用,同时保持灵活性。集成在组件级别进行。你还可以混合使用 React Native 组件、Expo UI 组件、DOM 组件 或使用
react-native-skia自定义的 2D 组件。
安装
🌐 Installation
你需要在你的 Expo 项目中安装 @expo/ui 包。运行以下命令来安装它:
🌐 You'll need to install the @expo/ui package in your Expo project. Run the following command to install it:
- npx expo install @expo/ui用法
🌐 Usage
Expo UI 提供了多个可用的 SwiftUI 组件。你可以通过从 @expo/ui/swift-ui 导入它们来在你的应用中使用它们。不过,要从 React Native(UIKit)跨界到 SwiftUI,你需要使用 Host 组件。Host 是 SwiftUI 视图的容器。你可以把它想象成 DOM 中的 <svg> 或 react-native-skia 中的 <Canvas>。在底层,它使用 UIHostingController 在 UIKit 中渲染 SwiftUI 视图。
🌐 Expo UI has several SwiftUI components available. You can use them in your app by importing them from @expo/ui/swift-ui. However, to cross the boundary from React Native (UIKit) to SwiftUI, you need to use the Host component. The Host is the container for SwiftUI views. You can think of it like <svg> in the DOM or <Canvas> in react-native-skia. Under the hood, it uses UIHostingController to render SwiftUI views in UIKit.
Host 的基本用法
🌐 Basic usage with Host
import { CircularProgress, Host } from '@expo/ui/swift-ui'; import { View, Text } from 'react-native'; export default function LoadingView() { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Host matchContents> <CircularProgress /> </Host> <Text>Loading...</Text> </View> ); }
使用 HStack 和 VStack
🌐 Using HStack and VStack
你也可以使用 HStack 和 VStack 组件在 SwiftUI 中构建整个布局。
🌐 You can also use the HStack and VStack components to build the entire layout in SwiftUI.
import { CircularProgress, Host, HStack, LinearProgress, VStack } from '@expo/ui/swift-ui'; export default function LoadingView() { return ( <Host style={{ flex: 1, margin: 32 }}> <VStack spacing={32}> <HStack spacing={32}> <CircularProgress /> <CircularProgress color="orange" /> </HStack> <LinearProgress progress={0.5} /> <LinearProgress color="orange" progress={0.7} /> </VStack> </Host> ); }
修饰符
🌐 Modifiers
SwiftUI 修饰符 是自定义 SwiftUI 组件外观和行为的一种强大方式。Expo UI 也为 SwiftUI 组件提供了修饰符。你可以从 @expo/ui/swift-ui/modifiers 导入修饰符,并将它们作为数组传递给 modifiers 属性。在下面的示例中,expo-mesh-gradient 和 glassEffect 修饰符结合使用,以创建液态玻璃文本。
注意:
glassEffect修饰符需要 Xcode 26 及以上版本和 iOS 26 及以上版本。
import { Host, Text } from '@expo/ui/swift-ui'; import { glassEffect, padding } from '@expo/ui/swift-ui/modifiers'; import { MeshGradientView } from 'expo-mesh-gradient'; import { View } from 'react-native'; export default function Page() { return ( <View style={{ flex: 1 }}> <MeshGradientView style={{ flex: 1 }} columns={3} rows={3} colors={['red', 'purple', 'indigo', 'orange', 'white', 'blue', 'yellow', 'green', 'cyan']} points={[ [0.0, 0.0], [0.5, 0.0], [1.0, 0.0], [0.0, 0.5], [0.5, 0.5], [1.0, 0.5], [0.0, 1.0], [0.5, 1.0], [1.0, 1.0], ]} /> <Host style={{ position: 'absolute', top: 0, right: 0, left: 0, bottom: 0 }}> <Text size={32} modifiers={[ padding({ all: 16, }), glassEffect({ glass: { variant: 'clear', }, }), ]}> Glass effect text </Text> </Host> </View> ); }
iOS 设置应用示例
🌐 iOS Settings app example
结合 Expo UI 组件和修饰符,你可以构建一个类似 iOS 设置应用的 UI。
🌐 Combining the Expo UI components and modifiers, you can build a UI like iOS Settings app.
import { Button, Form, Host, HStack, Image, Section, Spacer, Toggle, Text, } from '@expo/ui/swift-ui'; import { background, clipShape, frame } from '@expo/ui/swift-ui/modifiers'; import { Link } from 'expo-router'; import { useState } from 'react'; export default function SettingsView() { const [isAirplaneMode, setIsAirplaneMode] = useState(true); return ( <Host style={{ flex: 1 }}> <Form> <Section> <HStack spacing={8}> <Image systemName="airplane" color="white" size={18} modifiers={[ frame({ width: 28, height: 28 }), background('#ffa500'), clipShape('roundedRectangle'), ]} /> <Text>Airplane Mode</Text> <Spacer /> <Toggle isOn={isAirplaneMode} onIsOnChange={setIsAirplaneMode} /> </HStack> <Link href="/wifi" asChild> <Button> <HStack spacing={8}> <Image systemName="wifi" color="white" size={18} modifiers={[ frame({ width: 28, height: 28 }), background('#007aff'), clipShape('roundedRectangle'), ]} /> <Text color="primary">Wi-Fi</Text> <Spacer /> <Image systemName="chevron.right" size={14} color="secondary" /> </HStack> </Button> </Link> </Section> </Form> </Host> ); }
常见问题
🌐 Common questions
什么是 Host 组件?
Host 是 SwiftUI 视图的容器。你可以把它想象成 DOM 中的 <svg> 或 react-native-skia 中的 <Canvas>。在底层,它使用 UIHostingController 在 UIKit 中渲染 SwiftUI 视图。
Expo UI 与像 react-native-paper 或 react-native-elements 这样的库有何不同?
Expo UI 并不是“又一个”UI库,也不是一个有特定设计风格的设计套件。相反,它是一个原语库。它将本地的 SwiftUI 和 Jetpack Compose 组件直接暴露给 JavaScript,而不是在 JavaScript 中重新实现或模拟 UI。
🌐 Expo UI is not "yet another" UI library and not an opinionated design kit. Instead, it's a primitives library. It exposes native SwiftUI and Jetpack Compose components directly to JavaScript, rather than re-implementing or simulating UI in JavaScript.
我可以在 Android 或网页上使用 @expo/ui/swift-ui 吗?
Expo UI 的第一个里程碑是实现从 SwiftUI 到 Expo UI 的一对一映射。通用支持将在路由图的下一阶段实现。我们的首要任务是首先建立强大的 SwiftUI 支持,然后再扩展到 Android 上的 Jetpack Compose 和 Web 上的 DOM 支持。
🌐 The first milestone for Expo UI is achieving a 1-to-1 mapping from SwiftUI to Expo UI. Universal support will come in the next stage of the roadmap. Our priority is to establish strong SwiftUI support first, and then expand to Jetpack Compose on Android and DOM support on the Web.
我可以在 SwiftUI 组件中使用 React Native 组件吗?
是的,你可以将 React Native 组件作为 JSX 子组件放置在 Expo UI 组件中。Expo UI 会自动为你创建一个 UIViewRepresentable 封装器。
然而,请记住,SwiftUI 布局系统的工作方式与 UIKit 不同,并且存在一些限制。根据苹果的文档:
🌐 Yes, you can place React Native components as JSX children of Expo UI components. Expo UI automatically creates a UIViewRepresentable wrapper for you.
However, keep in mind that the SwiftUI layout system works differently from UIKit and has some limitations. According to Apple's documentation:
警告 SwiftUI 完全控制 UIKit 视图的
center、bounds、frame和transform属性的布局。不要在你自己的代码中直接设置由UIViewRepresentable实例管理的视图的这些布局相关属性,因为这样会与 SwiftUI 产生冲突,并导致未定义的行为。
还要注意,一旦你渲染 React Native 组件,就会离开 SwiftUI 上下文。如果你想再次添加 Expo UI 组件,则需要重新引入一个 Host 封装器。
🌐 Also note that once you render React Native components, you're leaving the SwiftUI context. If you want to add Expo UI components again, you'll need to reintroduce a Host wrapper.
我们建议保持 SwiftUI 布局的自包含性。虽然可以进行互操作,但在边界清晰定义的情况下效果最佳。
🌐 We recommend keeping SwiftUI layouts self-contained. Interop is possible, but it works best when boundaries are clearly defined.
我是一个 SwiftUI 开发者。我为什么要学习 Expo UI?
由于 React 承诺的“学一次,随处编写”,它现在已经扩展到 SwiftUI 和 Jetpack Compose。借助 Expo UI,你可以运用 SwiftUI 的知识来构建在 React Native 生态系统中运行的应用,通过 DOM 组件 扩展到 Web,甚至整合 2D 和 3D 渲染。该系统灵活到足以让应用的不同部分使用不同的方法——在组件级别实现无缝集成。
🌐 Because React's promise of "learn once, write anywhere", it now extends to SwiftUI and Jetpack Compose. With Expo UI, you can apply your SwiftUI knowledge to build apps that run in the React Native ecosystem, extend to the Web through DOM components, and even integrate 2D and 3D rendering. The system is flexible enough that different parts of your app can use different approaches — giving you seamless integration at the component level.
其他资源
🌐 Additional resources
有关 API 组件、方法等的信息,请参阅 Expo UI 参考。
我们最新的 Expo UI 示例
一个使用 Expo UI 复刻 YVR 热巧克力节应用的示例应用
TVOS 对 Expo UI 的支持