关于 iphone-duo-vertical-bars
面向 iPhone Duo 应用开发者的垂直工具栏设计技能,介绍系统侧边栏的启用条件、项目排列与溢出处理。涵盖 SwiftUI 和 UIKit 的 API 及不同显示状态下的行为。
主要功能
- 01通过导航容器启用垂直栏
- 02安排导航与显著操作
- 03为项目配置图标和标题
- 04控制轴向行为与溢出优先级
- 05处理自定义视图和栏压缩
适用场景
- 01将导航栏和标签栏适配到侧边
- 02确保按钮在各姿态位置一致
- 03调整工具栏项目的折叠顺序
- 04为垂直栏适配自定义控件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mirzaaghazadeh/ iphone-duo-skills --skill iphone-duo-vertical-bars安装后在 Claude Code 中输入/iphone-duo-vertical-bars确认已加载。
详细介绍
垂直轴上的栏
iPhone Duo 的显示屏比传统 iPhone 更宽、更矮。垂直空间非常有限,因此系统会将通常位于顶部和底部的控件移到侧边,那里也更靠近拇指。控件左侧的内容区域保持完整,与传统 iPhone 屏幕上的内容区域大小相当。
组件不变,轴向改变。用户以横向打开设备使用内屏时,控件的位置仍保持一致。只有一种姿态会保留横向栏:内屏竖屏显示,因为此时内容有充足的垂直空间。
启用条件
必须满足以下两项要求:
1. 使用最新 SDK 重新构建。 否则,栏会保持横向。
2. 使用来自导航容器的栏。 在 SwiftUI 中,将
toolbar 修饰符与 NavigationStack 或 NavigationSplitView 配合使用。在 UIKit 中,优先使用
UINavigationController 和 UITabBarController,它们会管理自己的栏——在视图控制器上设置工具栏项,并将其放入导航控制器中。
如果你使用 UIToolbar、UINavigationBar 或 UITabBar 手动创建栏,其内容不会被纳入垂直布局考量。这是应用的栏始终顽固地保持横向的最常见原因。
项目如何放置
导航、工具栏和标签栏控件会共存于同一个垂直区域。可以把横向栏想象成旋转 90° 后形成的垂直堆叠——根据屏幕不同,其中可能包含工具栏项、标签项,或两者兼有。
有两种结构上的例外:
- 分栏视图——只有详细内容列会参与布局。其他列中的项目仍保持横向。
- 检查器——展开时不会有自己的垂直栏,因为详细内容列已经有一个,再放一个会造成混乱。
工作表在不同显示屏上的表现有所不同。在外屏上,已有工具栏的工作表会将其显示为垂直栏。在内屏上,工作表居中显示,其中的项目保持横向。使用首选放置位置 API 移动工作表时,放置在右侧的工作表会显示垂直栏;放置在左侧的则不会。
栏会与硬件对齐,因此在从右到左的语言中,它仍位于同一物理侧。内容会围绕栏进行适配;栏本身不会移动。
排序项目
按照以下从上到下的层级,检查你的工具栏配置:
- 主要导航——返回、关闭。使用导航控制器时,系统会自动添加返回按钮。若要自定义返回或关闭操作,在 SwiftUI 中创建一个放置位置为
cancellationAction的ToolbarItem;在 UIKit 中,将项目添加到leadingItemGroups。 - 突出操作——完成等操作。在 SwiftUI 中使用
topBarPinnedTrailing放置位置,在 UIKit 中使用pinnedTrailingGroup。使用ToolbarItemPlacement语义对相关项目分组,而不要手动定位。 - 其他所有项目,保持原有分组方式。即使顶部和底部的放置位置合并到同一栏中,两者之间也会由垂直间隔区分。
并非所有姿态都会以垂直方向排列栏,因此请保持放置位置一致。每次打开设备时,用户都不应该需要重新学习某个操作的位置。
符号还是文本
大部分精致度都取决于这一点。
水平栏为项目提供固定高度和灵活宽度。垂直栏则相反:固定宽度,灵活高度。因此,窄而高的布局更适合仅显示符号。
系统会根据你提供的图标和标题选择显示形式——在栏中可见时显示图标,没有图标时显示文本,项目移入溢出菜单后则同时显示。这些规则都不会改变。新增的是,系统还会判断项目是否适合垂直方向:带图标的项目会垂直排列,仅含文本的项目则保持水平排列。
因此:始终同时提供标题和图像,即使你预期会使用图像也是如此。使用 SwiftUI Label 或对应的 UIBarButtonItem 属性。项目移入溢出菜单或展开形式时,系统会回退显示标题。
使用轴行为进行覆盖
系统通常能正确推断。如果判断不对,可以覆盖:在 SwiftUI 中使用 .axisBehavior(_:) 修饰符并传入 ToolbarItemAxisBehavior,或在 UIKit 中使用 UIBarButtonItem.axisBehavior(类型为 UIBarButtonItem.AxisBehavior)。
强制水平排列适用于会在符号和文本之间切换的项目,例如从编辑按钮变成“完成”按钮。即使符号可以放在垂直栏中,文本形式却不行,而项目在不同轴之间跳转会显得突兀。系统的“编辑”按钮已经处理了这种情况;自定义的对应按钮则需要设为仅水平排列。通常应让相关项目保持在同一轴上。
允许垂直排列适用于自定义视图:系统原本会让它保持水平排列,但它确实有合适的垂直形式。
减少文本,让更多项目可以垂直排列
尽量减少仅含标题的项目,以及将文本与图像搭配显示的自定义视图。大多数情况下,符号更合适。例如,图标旁内联显示的计数可以变成符号上的徽标——iOS 26 的徽标 API 可在所有设备上提供标准外观——从而将混合项目变为仅显示符号的项目。
判断标准:文本是在强化符号,还是在传达符号无法表达的信息? 辅助文本可以省去。显示累计总额的购物车按钮则不行——应让它保持水平排列。
键盘附件栏始终附着在键盘上,绝不会切换到垂直轴。
自定义视图
选择加入的自定义视图必须适应栏的固定宽度,或自行改为垂直布局。重新审视它们的尺寸指标——垂直排列时,控制面板可以隐藏标签并稍微缩小,以腾出空间。
要据此调整布局,请读取 toolbarVerticalEdge(SwiftUI 中的环境值,UIKit 中的特征)。你可以在内容视图中读取,也可以在项目自身的视图内部读取。
请仔细理解其语义,因为很容易弄反。它是一个 HorizontalEdge?,报告的是**当前上下文中,系统更倾向于将垂直栏放在哪一侧——无论垂直栏实际上是否可见。**因此,它不是“我的项目现在是否改为垂直排列?”的标志,而是“如果这里有垂直栏,它应该位于这一侧”,这正是你将自定义栏和锚定于边缘的 UI 与系统布局对齐所需要的信息。
还有两个值得了解的行为细节:默认情况下,垂直栏没有滚动边缘效果;但开启“降低透明度”后,它会显示背景,因此无论哪种情况,都要确保自定义内容清晰易读。此外,弹性间隔会在垂直轴上收缩为零,而固定间隔会保留其最小尺寸——不过,你的应用不应在任何一个轴上手动添加栏间距。
用分组代替间距。 不要手动插入间隔,而要表达项目之间的关系:在 SwiftUI 中使用 ToolbarItemGroup,在 UIKit 中使用 UIBarButtonItemGroup。分组会根据相邻分组自动调整间距,并随着可用空间变化重新排布——在这台设备上,这种变化会不断发生。手动间距是固定的,而此时恰恰需要灵活调整。
让控件靠近其作用对象。 如果某个控件属于非末端内容区域,就让它留在该区域,而不要将它移到侧边栏。靠近作用对象,才能让人明白该控件适用于那个窗格。在邮件式布局中,操作邮件列表的控件应放在列表上方,而不是放进共享的垂直栏中,否则看起来就像是用于当前打开的邮件。
溢出
这里的项目更容易溢出——横屏时,外屏的垂直空间很小,键盘或固定的“画中画”等其他 UI 还会进一步挤占空间。
首先决定哪一类内容应尽可能保留:工具栏项目还是标签栏。
- 由导航驱动的屏幕应让工具栏优先压缩,确保主要目的地仍可访问。这是默认行为。
- 由任务驱动的屏幕应让标签栏优先压缩,以保留常用操作。
可通过工具栏压缩行为 API 为每个视图配置此项。
整合到系统溢出菜单中。 如果应用有自己的溢出菜单,请将其中的操作合并到系统管理的菜单中——SwiftUI 使用 ToolbarOverflowMenu,UIKit 使用 UINavigationItem.additionalOverflowItems。省略号符号应专用于溢出菜单;其他菜单应使用各自独特的符号,不要照搬其他平台的惯例。
然后设置优先级。 默认情况下,项目按从下到上的顺序溢出。分配可见性优先级——SwiftUI 使用 ToolbarItemVisibilityPriority,UIKit 使用 UIBarButtonItemVisibilityPriority——以控制收缩顺序。优先级应先按分组设置;如果需要更精细的控制,再在组内设置。
有两类内容应设为高优先级:人们经常使用的操作(撰写、新建笔记),以及传达状态的控件(例如带徽标的项目);它们一旦隐藏,就毫无用处。
何时关闭
默认答案:不要关闭。 侧边控制是这款设备的标志性设计模式,而 Apple 的指导明确指出,通常不应覆盖其位置。熟悉的控件位置能让用户拿起你的应用就知道如何使用,而每个选择退出的应用都会削弱这一点。
合理的例外情况很少:
- 完全不需要栏的界面——例如计算器式布局,横跨整个显示屏宽度。这适用于视觉沉浸式、非滚动界面,前提是没有任何内容与 Dynamic Island 或状态栏冲突。你也可以混合使用:背景或标题栏占满宽度,滚动内容则采用内缩布局。
- 控件较少的工作表,其中一个关闭按钮不足以成为放弃宽度的理由。
使用 toolbarVerticalBehavior(SwiftUI)或 preferredVerticalBarBehavior(UIKit)退出。在外屏上退出的工作表会停在前置摄像头之前一点,状态栏也会重新定位。
检查清单
- 使用最新的 SDK 重新构建。
- 将手动实现的栏替换为容器提供的栏。
- 为每个项目同时提供标题和图像。
- 按顺序排列项目:导航、醒目的操作,然后是其余项目。
- 如果文字只是补充说明,将文字加符号的项目改为带徽章的符号。
- 对在符号和文字之间切换的项目应用
.axisBehavior(_:)/UIBarButtonItem.axisBehavior。 - 针对每个视图选择工具栏优先或标签栏优先的压缩方式。
- 将自定义溢出菜单整合到系统菜单中,并设置
visibilityPriority。 - 在 Device Hub 中验证每种设备姿态,包括两侧的 Split View。