Design for the iPadOS pointer
Design 进阶 25m

为 iPadOS 指针做设计

Design for the iPadOS pointer

2020年6月23日

在 Apple 官方观看视频

一句话判断

iPad 上的鼠标/触控板指针不是传统桌面系统的小箭头——它是一个有弹性、有感知、会变形的交互元素。如果你在做 iPad App,这场 Session 帮你理解这个全新交互范式的每个细节。

这场 Session 讲了什么

这场 Session 由 Apple 的设计团队主讲,深入讲解了 iPadOS 指针交互的设计哲学和实现细节。iPadOS 13.4 引入了触控板和鼠标支持,但 Apple 没有简单地把 macOS 的指针搬过来——他们设计了一套全新的指针系统。

演讲者首先介绍了 iPadOS 指针的核心设计原则:Aim & Morph(定位与变形)。默认状态下,指针是一个圆形光标,用于精确指向屏幕上的元素。当指针接近可交互元素时,它会”吸附”并”变形”——变成按钮的形状、滑块的高度、或者文本的 I-beam。这种变形不是简单的视觉特效,它传达了”这个元素是可交互的”和”点击它会发生什么”两层信息。

Session 详细讲解了不同 UI 元素的指针行为:按钮(吸附并变圆角矩形)、文本(变成 I-beam 光标)、滑块和进度条(沿轴线吸附)、Tab Bar(水平吸附到 Tab 项上)。演讲者还介绍了如何为自定义控件设计自定义的指针吸附行为。

最后讨论了指针交互与手势的关系——触控板的手势(双指滑动、捏合缩放)如何映射到 App 的操作,以及如何确保手势和指针点击的一致性。

值得深挖的点

  • “Snap to Edge” 的设计:当指针移到屏幕边缘时,它不会消失——而是”吸附”到边缘的控件上。比如移动到顶部边缘会吸附到状态栏,移动到右上角会吸附到控制中心图标。这个设计解决了”在小触摸板上把指针移到屏幕角落很困难”的问题。
  • 指针交互与辅助功能的关系:iPadOS 指针的大小、颜色、动画速度都可以在设置中调节。对于手部灵活性受限的用户,可以增大指针和吸附范围。你的自定义指针行为必须尊重这些系统设置。

代码片段

// 为自定义 UI 元素配置指针交互
import UIKit

class CustomButton: UIButton {
    override func didMoveToSuperview() {
        super.didMoveToSuperview()

        // 添加指针交互
        let pointerInteraction = UIPointerInteraction(
            delegate: self
        )
        addInteraction(pointerInteraction)
    }
}

extension CustomButton: UIPointerInteractionDelegate {
    func pointerInteraction(
        _ interaction: UIPointerInteraction,
        styleForRegion region: UIPointerRegion
    ) -> UIPointerStyle? {
        // 指针在按钮上方时变形为按钮形状
        let preview = UITargetedPreview(view: self)
        return UIPointerStyle(effect: .highlight(preview))
    }
}
// 为自定义视图设置指针吸附区域
class CustomSlider: UIView, UIPointerInteractionDelegate {
    func pointerInteraction(
        _ interaction: UIPointerInteraction,
        regionFor request: UIPointerRegionRequest,
        defaultRegion: UIPointerRegion
    ) -> UIPointerRegion? {
        // 指针在滑块范围内时沿水平方向吸附
        let rect = trackRect(forBounds: bounds)
        return UIPointerRegion(rect: rect)
    }

    func pointerInteraction(
        _ interaction: UIPointerInteraction,
        styleForRegion region: UIPointerRegion
    ) -> UIPointerStyle? {
        // 指针变形为窄条状
        return UIPointerStyle(
            effect: .custom(UITargetedPreview(view: thumbView))
        )
    }
}
// 全局禁用特定视图的指针交互
class NonInteractiveOverlay: UIView {
    override func didMoveToSuperview() {
        super.didMoveToSuperview()

        // 禁用指针吸附,让指针直接穿过
        let interaction = UIPointerInteraction(delegate: nil)
        addInteraction(interaction)
    }
}

// 在 UIScrollView 中处理指针
// ScrollView 默认已支持指针交互
// 包括滚动吸附和滚动指示器显示
class CustomScrollView: UIScrollView {
    override var canBecomeFocused: Bool {
        return true  // 允许指针聚焦
    }
}

最佳实践

  • 所有可点击的 UI 元素都应该添加指针交互,让指针在接近时变形
  • 自定义指针形状要与系统行为一致——不要创造用户无法理解的指针形态
  • 尊重系统设置中的指针大小和颜色偏好
  • 指针变形的动画要自然流畅,使用系统默认的动画曲线
  • 不要让指针吸附到不可交互的装饰性元素上——这会误导用户

还有什么值得关注

  • iPadOS 指针的设计语言后来在 visionOS 中演变为眼动追踪的注视反馈
  • 如果你在做跨平台 App,iPad 和 Mac 上的指针行为需要保持一致
  • “Bring keyboard and mouse gaming to iPad” 讲解了游戏场景下的指针处理
WWDC 2020