列表交互

本示例展示如何在 Scripting 应用中通过左右滑动手势为 List 列表项添加交互操作。借助 leadingSwipeActionstrailingSwipeActions,你可以实现诸如标记未读、删除、标记重点等常见功能。


概览

你将学会如何:

  • 使用自定义单元格显示消息列表
  • 为列表项添加左右滑动手势操作
  • 配置滑动行为(例如禁止全滑触发)
  • 结合 ButtonLabelCircle 等组件构建交互界面

示例代码

1. 定义消息数据类型

1type Message = {
2  from: string
3  content: string
4  isUnread: boolean
5}

2. 创建自定义消息单元格组件

使用 HStackVStack 展示每条消息的状态指示点、发件人和内容。

1function MessageCell({
2  message
3}: {
4  message: Message
5}) {
6  return <HStack>
7    <Circle
8      fill={message.isUnread ? "systemBlue" : "clear"}
9      frame={{
10        width: 16,
11        height: 16,
12      }}
13    />
14    <VStack alignment={"leading"}>
15      <Text font={"headline"}>{message.from}</Text>
16      <Text>{message.content}</Text>
17    </VStack>
18  </HStack>
19}

3. 管理列表状态与操作

1const [messages, setMessages] = useState<Message[]>(...)
2
3function toggleUnread(message: Message) {
4  setMessages(messages.map(item =>
5    item !== message ? item : { ...message, isUnread: !item.isUnread }
6  ))
7}
8
9function deleteMessage(message: Message) {
10  setMessages(messages.filter(item => item !== message))
11}

4. 构建带滑动交互的列表视图

1return <NavigationStack>
2  <List
3    navigationTitle={"Messages"}
4    navigationBarTitleDisplayMode={"inline"}
5    listStyle={"inset"}
6  >
7    {messages.map(message =>
8      <MessageCell
9        message={message}
10        leadingSwipeActions={{
11          allowsFullSwipe: false,
12          actions: [
13            <Button
14              action={() => toggleUnread(message)}
15              tint={"systemBlue"}
16            >
17              {message.isUnread
18                ? <Label title={"Read"} systemImage={"envelope.open"} />
19                : <Label title={"Unread"} systemImage={"envelope.badge"} />
20              }
21            </Button>
22          ]
23        }}
24        trailingSwipeActions={{
25          actions: [
26            <Button
27              role={"destructive"}
28              action={() => deleteMessage(message)}
29            >
30              <Label title={"Delete"} systemImage={"trash"} />
31            </Button>,
32            <Button
33              action={() => {}}
34              tint={"systemOrange"}
35            >
36              <Label title={"Flag"} systemImage={"flag"} />
37            </Button>
38          ]
39        }}
40      />
41    )}
42  </List>
43</NavigationStack>

5. 展示页面并退出脚本

1async function run() {
2  await Navigation.present({
3    element: <Example />
4  })
5
6  Script.exit()
7}
8
9run()

关键特性

  • leadingSwipeActions:配置从主视图起始方向滑动(如从左向右)的操作。
  • trailingSwipeActions:配置从主视图尾部方向滑动(如从右向左)的操作。
  • allowsFullSwipe:设置为 false 时,禁止通过完全滑动直接触发第一个操作按钮。
  • Button 的 role 属性:使用 "destructive" 等角色值,系统会为按钮应用相应的视觉样式(如删除按钮为红色)。
  • tint:可自定义按钮颜色,以提升识别度与视觉分层。

适用场景

  • 邮件/消息类脚本:快速标记为已读/未读、删除、归档或加星。
  • 任务清单:滑动完成任务或移除待办事项。
  • 自定义工具列表:根据上下文为每项内容添加快捷操作。

通过滑动操作,可以为列表提供直观、高效的交互方式,提升用户体验与操作效率。