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

SwiftUI

用于使用 @expo/ui 构建原生 iOS 界面的 SwiftUI 组件。

iOS
tvOS
Included in Expo Go
Recommended version:
~57.0.22

@expo/ui/swift-ui 中的 SwiftUI 组件允许你使用 SwiftUI 从 React Native 构建完全原生的 iOS 界面。

🌐 The SwiftUI components in @expo/ui/swift-ui allow you to build fully native iOS interfaces using SwiftUI from React Native.

安装

🌐 Installation

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.

用法

🌐 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.

import { Host, Button } from '@expo/ui/swift-ui'; export function SaveButton() { return ( <Host style={{ flex: 1 }}> <Button label="Save changes" /> </Host> ); }
使用 SwiftUI 扩展

创建与 Expo UI 集成的自定义 SwiftUI 组件和修饰符。

Expo UI iOS 液态玻璃教程
Expo UI iOS 液态玻璃教程

了解如何在你的 React Native 应用中使用新的 Expo UI 构建真实的 SwiftUI 视图。

可用组件

🌐 Available components

示例

🌐 Examples

修饰符

🌐 Modifiers

SwiftUI 修改器 可以自定义 SwiftUI 组件的外观和行为。Expo UI 也为 SwiftUI 组件提供了修改器。你可以从 @expo/ui/swift-ui/modifiers 导入修改器,并作为数组传递给 modifiers 属性。在下面的例子中,expo-mesh-gradient 和 glassEffect 修改器被组合,用来创建 Liquid Glass 文字效果。

GlassEffectExample.tsx
import { Host, Text } from '@expo/ui/swift-ui'; import { font, glassEffect, padding, } from '@expo/ui/swift-ui/modifiers'; import { MeshGradientView } from 'expo-mesh-gradient'; import { View } from 'react-native'; export default function GlassEffectExample() { 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 modifiers={[ font({ size: 32 }), padding({ all: 16, }), glassEffect({ glass: { variant: 'clear', }, }), ]}> Glass effect text </Text> </Host> </View> ); }

iOS 设置应用

🌐 iOS Settings app

结合 Expo 的 UI 组件和修饰符,你可以做出像 iOS 设置应用一样的界面。

🌐 Combining the Expo UI components and modifiers, you can build a UI like the iOS Settings app.

SettingsFormExample.tsx
import { Button, Form, Host, HStack, Image, Section, Spacer, Toggle, Text, } from '@expo/ui/swift-ui'; import { background, buttonStyle, foregroundStyle, clipShape, frame, } from '@expo/ui/swift-ui/modifiers'; import { Link } from 'expo-router'; import { useState } from 'react'; export default function SettingsFormExample() { 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> {/* Use buttonStyle('plain') to prevent default blue button styling */} <Button modifiers={[buttonStyle('plain')]}> <HStack spacing={8}> <Image systemName="wifi" color="white" size={18} modifiers={[ frame({ width: 28, height: 28 }), background('#007aff'), clipShape('roundedRectangle'), ]} /> {/* Text inside a Link needs an explicit color. A hierarchical style adapts to light and dark mode. */} <Text modifiers={[ foregroundStyle({ type: 'color', color: 'primary', }), ]}> Wi-Fi </Text> <Spacer /> <Image systemName="chevron.right" size={14} color="secondary" /> </HStack> </Button> </Link> </Section> </Form> </Host> ); }

次要文本样式

🌐 Secondary text styling

使用 foregroundStyle 来应用 分层样式,可以让文字看起来更轻、更微妙。

🌐 Use foregroundStyle to apply a hierarchical style, which makes text appear lighter and more subtle.

SecondaryTextExample.tsx
import { Button, Form, Host, HStack, Image, List, Section, Spacer, Text, } from '@expo/ui/swift-ui'; import { buttonStyle, font, foregroundStyle, padding, } from '@expo/ui/swift-ui/modifiers'; export default function SecondaryTextExample() { return ( <Host style={{ flex: 1 }}> <Form> <Section> <List> <Button onPress={() => console.log('Navigate')} modifiers={[buttonStyle('plain')]}> <HStack> <Text>Night Shift</Text> <Spacer /> <Text modifiers={[ foregroundStyle({ type: 'hierarchical', style: 'secondary', }), padding({ trailing: 8 }), ]}> 22:00 to 07:00 </Text> <Image systemName="chevron.right" size={14} color="#C7C7CC" /> </HStack> </Button> </List> <List> <Text modifiers={[ foregroundStyle({ type: 'hierarchical', style: 'secondary', }), font({ size: 14 }), ]}> Save up to 280.7 MB. This will permanently delete all photos and videos kept in the "Recently Deleted" album. </Text> </List> </Section> </Form> </Host> ); }

带图标的滑块

🌐 Slider with icons

亮度或音量控制的常见模式是用图标将 Slider 两侧包围。

🌐 A common pattern for brightness or volume controls is to flank a Slider with icons.

SliderWithIconsExample.tsx
import { useState } from 'react'; import { Form, Host, HStack, Image, List, Section, Slider, Spacer, Text, Toggle, } from '@expo/ui/swift-ui'; import { padding } from '@expo/ui/swift-ui/modifiers'; export default function SliderWithIconsExample() { const [brightness, setBrightness] = useState(0.5); const [trueToneEnabled, setTrueToneEnabled] = useState(true); return ( <Host style={{ flex: 1 }}> <Form> <Section header={<Text>Brightness</Text>} footer={ <Text> Automatically adapt iPhone display based on ambient lighting conditions to make colors appear consistent in different environments. </Text> }> <List> <HStack modifiers={[padding({ vertical: 6 })]}> <Image systemName="sun.min.fill" size={22} color="#8E8E93" /> <Spacer /> <Slider value={brightness} onValueChange={setBrightness} /> <Spacer /> <Image systemName="sun.max.fill" size={22} color="#8E8E93" /> </HStack> <Toggle label="True Tone" isOn={trueToneEnabled} onIsOnChange={setTrueToneEnabled} /> </List> </Section> </Form> </Host> ); }

多行列表项

🌐 Multi-line list items

将 VStack 与 alignment="leading" 一起用于带有标题和副标题的列表项。

🌐 Use VStack with alignment="leading" for list items with a title and subtitle.

MultiLineListItemExample.tsx
import { Button, Form, Host, HStack, Image, List, Section, Spacer, Text, VStack, } from '@expo/ui/swift-ui'; import { buttonStyle, font, foregroundStyle, padding, } from '@expo/ui/swift-ui/modifiers'; export default function MultiLineListItemExample() { return ( <Host style={{ flex: 1 }}> <Form> <Section> <List> <HStack> <Image systemName="safari" size={22} modifiers={[padding({ trailing: 6 })]} /> <Spacer /> <Button onPress={() => console.log('Navigate')} modifiers={[ buttonStyle('plain'), padding({ vertical: 6 }), ]}> <VStack spacing={4} alignment="leading"> <Text>Chrome</Text> <Text modifiers={[ foregroundStyle({ type: 'hierarchical', style: 'secondary', }), font({ size: 14 }), ]}> Last used: Today </Text> </VStack> <Spacer /> <Text modifiers={[ foregroundStyle({ type: 'hierarchical', style: 'secondary', }), font({ size: 16 }), ]}> 1.57 GB </Text> <Image systemName="chevron.right" size={14} color="#C7C7CC" /> </Button> </HStack> </List> </Section> </Form> </Host> ); }