大多数浏览器和
Developer App 均支持流媒体播放。
-
面对 iPadOS 指针进行开发
为结合妙控键盘、鼠标、触摸板或其他输入设备使用 iPad 的用户提供便利,让他们也能最大限度利用你的 app。我们将向你展示如何使用指针互动 API,为 iPad 指针增添自定义功能、为你对按键与自定义浏览创建指针效果、在你 app 的特定区域内更改指针形状并令其高亮显示。 要了解更多关于 iPad 指针互动的内容、最大限度利用本节课程,我们建议你观看“面对 iPadOS 指针进行设计”与“处理触控板与鼠标输入”等节。
资源
相关视频
WWDC23
WWDC21
WWDC20
-
下载
(你好 WWDC 2020)
你好 欢迎来到 WWDC
嗨 我是负责 UIKit 的工程师 Mohammed 稍后 来自 iOS 系统用户界面团队的 我的同事 Joey 也会加入进来 本次内容是“如何为 iPadOS 构建光标” 在 13.4 版本中 iPadOS 给 iPad 添加了常规的光标设备载体 对于 OS 这种 从一开始就主要基于触控的操作系统来说 这是一种全新的输入方法 我们没有只是照搬 Mac 上存在的交互模型 而是考虑了光标可以为 iPadOS 添加的价值 以及它如何与基于触控的界面共存
其结果是 一个建立在流体自适应光标上的系统 当悬停在控件上时 它会变形成控件 以适应其精确度 并清楚表明你将要与它们进行交互 在其他情境中 光标会变换其形状及动态特征 以提供相关提示 (向那些疯狂的人们致敬…) 例如 当光标悬停在文本上时 会变成一个光束 可快速在文本间移动 从而使与文本的交互更加容易 在此视频中 我们将讨论更新 iPadOS 光标 我们所遵循的策略 以及你在更新 app 时 如何使用相同的策略
在讨论过程中 我们将讲到 iOS 13.4 版本中引入的 自定义光标 API 以及在更新 app 时 要牢记的一些最佳做法
我们还将介绍用户界面光标背后的 一些基本设计原则 有关这些原则 以及一些光标设计背后思考过程的 更详细的讨论 请查看 iPadOS 光标的设计讲座 (可用的设备) 当你使用连接了光标设备的 iPad 时 你会注意到很多东西都可以自动使用光标 无需 app 额外的适配 这是因为许多系统组件 都设有内置的光标支持 诸如 UIBarButtonItem UISegmentedControl 以及 UIMenuController 等控件 都有内置的光标效果和行为
滚动视图可以通过两根手指滚动 以及鼠标滚轮滚动 在触控板上可以捏合来实现缩放
除了这些滚动视图基础操作之外 集合视图和桌面视图现在还支持两指平移 以进行轻扫操作
UITextView 和 其他使用 UITextInteraction 的组件 支持一套使用 Mac 的人应该都熟悉的 新的快速文本选择和编辑手势
UIDragInteraction 现在允许 通过点击和拖动来快速拖动 而无需像触控一样长按
UIContextMenuInteraction 允许通过右键点击 以一种新的简洁的表现方式调用其菜单
那么 我们该如何为光标更新 app 呢? (更新你的 app) 我们发现最好采取自上而下的方法 从更高级别的 API 开始 它们将通过与系统其他部分 类似用户界面保持一致的 调优行为和视觉效果 为你提供最完美的体验 在堆栈的不同级别 有许多与光标相关的 API 可供你使用 许多控件具有内置的光标效果 某些控件 例如栏按钮和分段控件 它们的效果是默认启用的 而其他控件 例如用户界面按钮 提供允许你启用和自定义效果的 API
通过 UIPointerInteraction 你可以使你的自定义用户界面 用与系统其他部分一致的方式 对光标做出反应并与之交互 使用交互 你可以从系统提供的效果集合中 选择一个应用于视图 或者可以在 app 的某个区域内 改变光标的形状 UIHoverGestureRecognizer 允许 更直接地响应光标的动态 这对于任何 不涉及应用悬停或高亮显示效果 或修改光标外观的自定义行为都是很好的 有关此手势 和其他与光标相关的手势和事件的 详细信息 请查看有关处理触控板和鼠标输入的讲座 当你更新你的 app 时 你希望获得一种 与 OS 其余软件相一致的体验 在决定在何处添加光标支持时 请参考 Human Interface Guidelines 和内置 app 为此 一个好的出发点 是确保你的 app 的 chrome 的控件 具有适当的效果 这里的“chrome”是指 app 的顶部和底部栏 所以要从 app 中的任何栏按钮开始
使用系统项、图像或标题 API 创建的 UIBarButtonItems 将自动获得适当的光标效果
如果使用自定义视图 API 则必须自己执行光标行为 或者使用视图的便捷 API 如果有的话 或者安装光标交互并自己管理效果
通过自定义视图 API 放置在栏中的 用户界面按钮 默认启用了内置交互 并被赋予包含在栏中的按钮 系统认为适合的效果
你可以使用用户界面按钮的便捷 API 来调整这种效果
为了使这变得非常简单 用户界面按钮有一个两阶段的便捷 API 要启用自动效果 只需将按钮的 isPointerInteractionEnabled 的 属性设置为“真” 启用该效果后 可以用按钮的 pointerStyleProvider 对其进行自定义
在本闭包中 系统将根据 按钮的外观、大小和内容 为你提供建议的效果和形状
在这里 你可以自定义它们中的任何一个 或完全替换它们并构建一个新的样式
在我们看一些例子之前 让我们先简单谈谈光标样式
所有修改光标外观的 API 都使用 UIPointerStyle 来描述它们应用的修改
样式分为两类
首先是我们所说的内容效果
内容效果通常会致使 光标变为 app 中的视图 并对其进行一些视觉处理
一个常见的例子是 应用于栏按钮的高亮显示效果 其中光标变形成一个圆角矩形 在按钮下滑动 并给它添加了一个微妙的视差效果
此样式包括一个 UIPointerEffect 它描述了应用于视图的视觉处理… 以及一个 UIPointerShape 它描述了光标将更改为的形状
为了指定这种效果 我们构造了一个 UIPointerStyle 其中高亮显示效果和圆角矩形 作为光标形状
第二类是形状自定义 通过 UIPointerShape 和 UIAxis 遮盖来表示
应用时 光标将变形为形状 并受到当前区域内的指定轴的约束
这方面的一个很好的例子是 文本视图中的光标行为 我们使用一个垂直的光束作为形状 并指定“垂直”作为约束轴 以使光标感觉像是 在沿着文本线的水平轨道上
有了控件 API 和光标样式的基本概述 现在我将交给 Joey 让他来演示 如何将它们应用到现有的 app 中 Joey ? 谢谢 Mohammed 今天我们来看一个我一直在开发的 叫做缝制模拟器的 app 我自己不太会缝制东西 但我一直在学习缝制 因为我研发了这个 app 让我来构建和运行看看 我们到目前为止的进程
我们首先要看的是右下角的这个按钮 它可以打开或关闭直线引导模式 使缝线更容易成为一条直线 你可以看到它使用了高亮效果 但似乎不太对 效果大小不对
让我们切换回 Xcode 看看能做些什么来改进它
在这里我们可以看到 按钮的光标交互已经启用 自动呈现出默认效果 我们可以为此标尺按钮添加 pointerStyleProvider 来改进形状
首先我们创建一个矩形 以适当的数量 从按钮的边界开始
然后将该矩形转换为 所建议效果预览的目标的坐标空间
最后 返回一个基于矩形 使用了建议效果 已改进的光标形状样式 让我们看看变化
好多了 这个按钮看起来不错 而且感觉更舒服
接下来 让我们把注意力转向右上角的 线程选择器按钮 此按钮使用当前选定的线程颜色更改颜色
我已经自定义这个按钮栏 使用提升的效果 因为它有一个内在的形状 可以看到这里不太对劲 当光标接近按钮时 我们会看到按钮下的漫反射模糊效果 这会分让人分心 是不对的 让我们切换回 Xcode 来解决这个问题
因为它是一个 UIBarButtonItem 所以默认情况下 它已经获得了一个效果 我们再次修改 pointerStyleProvider 这次将默认效果更改为提升效果 但是这个执行是不正确的 所以让我们用正确的形状来修复它
在这个更新的执行中 我们创建了 一个新的 UITargetedPreview 适合用于提升效果 它是用我们前面创建的视图、目标 以及预览参数创建的
参数的 shadowPath 属性设置为 与按钮轮廓匹配的路径
最后 闭包使用此预览创建的提升效果 和与按钮匹配的光标形状 返回光标样式
现在回到 iPad 来看看它的改进
现在情况看起来不错 当我们用光标接近它时 这段线程才活跃起来
Mohammed 交回给你 谢谢 Joey 既然我们已经了解了如何增强控件 让我们来谈谈自定义用户界面
在考虑向自定义用户界面添加光标行为时 请注意那些你认为 它们会添加实用功能和独特价值的地方
我们的缝制模拟器 app 在中间有很大的区域 点击一次 就开始一针 然后在其他位置再次点击完成缝合 通过执行一些自定义光标行为 我们可以做一些事情来改进体验 让我们添加两个增强功能
首先 当悬停在缝制区域上时 让我们更改光标的形状 以明确点击某个定位将开始缝制
让我们为初学者添加一个引导模式 其中光标被限制在垂直轴上 使其更容易做完美的水平缝合
因为这是一个完全自定义的视图 我们将直接用 UIPointerInteraction 来实现我们的目标 与其他交互用户界面一样 我们创建 UIPointerInteraction 的实例 并将其附加到视图 但是 与其他交互不同的是 此交互的委托是可选的
正如我们对 app 中的控件所做的那样 我们将使用 UIPointerStyles 来指定要应用于光标的效果或形状变化 由于我们希望对样式的活动位置 进行细粒度的控制 因此我们还将定义 自定义 UIPointerRegions 以指示交互在何处应用我们提供的样式
默认情况下 交互使用覆盖整个视图的区域
如果委托不提供任何样式 交互会将自动光标效果应用于整个视图
在一些简单的情况下 这是非常方便的 譬如我们希望一个视图只应用一个效果 但我们的情况更专业一点
因为我们想在视图的特定子区域内 定义行为 所以我们要执行 UIPointerInteractionDelegate 的 regionFor 请求方法
当光标在交互视图中移动时 调用此方法以请求新区域 为了执行此方法 我们将为它提供与引导相对应的区域
光标一进入区域 交互就调用其委托的 styleForRegion 方法 来请求样式 因此我们需要执行该方法 并返回提供此十字线形状的 形状定制样式
现在我要交回给 Joey 看看在实践中是什么样子
再次感谢 Mohammed 让我们再看看缝制模拟器 看看可以如何改进它 一旦缝制者选择了一种线的颜色 就该开始缝制了 通过在拼缝区域点击每个缝针 这是很容易完成的
首先我要选一些黄色的线
我可以利用 UIScrollView 的功能 用两个手指放大…
我先在这里缝几针开始
通过指定自定义光标形状 和帮助用户使用自定义区域 可以很好地利用光标的激光精度
我们要做的第一件事是 将自定义光标交互添加到视图中
这将创建一个以“自身”作为委托的 新 UIPointerInteraction 并将其添加到缝制视图中
我已经执行了 styleForRegion 的 委托方法 第一行创建一个 UIPointerShape 对象 该对象具有从帮助方法获得的 自定义贝兹曲线
第二个创建并返回 使用光标形状的 UIPointerStyle 让我们看看是什么样子
好多了 用这样精巧的线程感觉更自然 让我们回到前面提到的直线引导 如果我通过点击标尺按钮把它打开…
然后缝几针…
很明显可以看到 产生优秀的结果是多么容易
不过这让人有点迷惑 光标可以自由移动 但是缝合线只在网格线上出现
让我们看看能做些什么
我们可以修改委托方法执行方式 来限制光标垂直移动 这样光标就被约束到了每一行 首先 我将添加一个 regionForRequest 的执行 为每个指引提供不同的区域
如果我们使用 StraightLineStitch 模式 那就提供一个单独的区域 即网格线的高度
否则 返回默认区域
接下来 我们将限制光标在垂直轴上的移动
如果我们使用引导 则返回十字准线 并将约束轴设置为“垂直” 否则 与之前相同
如你所见 我们已经增强了该 app 的直线缝合功能 当我移动光标时 它会落在水平方向的引导线上 光标几乎是被磁力吸到它相应的地方 这就是演示的内容 交回给你 Mohammed 再次感谢 Joey 看上去很不错 现在让我们来讨论一些 你可以采取的额外步骤 来为你的 app 定制光标体验 (改善) 你可以做一些小事情 来改善你的 app 中的光标体验 其中一个改善方法就是 在视图周围提供扩展的填充 来增强光标的吸引力 并使其更容易 与用户界面中的重要元素交互 正如你所看到的 光标在到达该按钮的边缘之前 就捕捉到该按钮
这是通过提供一个光标区域来完成的 该光标区域扩展了光标样式的有效区域
需要注意的是 你提供的任何区域 都必须包含在交互视图的 可命中测试区域中 如果提供的区域大于视图 还必须通过覆盖命中测试方法 来确保该区域对视图进行命中测试
通过调整光标区域 我们可以精确地控制 光标在效果之间转换的时间和方式 在提醒事项 app 的这个例子中 我们可以看到 即使这些视图在视觉上是分开的 但光标在它们之间无缝地转换 而不会在间隙中回到系统形状
这是通过提供与连续光标区域的 交互来实现的
在协调多个光标区域或样式时 将交互提升到视图层次结构中的 更高级别 通常是有意义的 你可以对用户界面有更完整的了解 并可以有更全局性的理解
在本例中 交互附加到了整个视图 其委托为各个子视图提供区域
另一个很好的方法是 用光标交互的动画来协调其他动画 这是一个显示有用的信息 或隐藏无关的 chrome 以减少效果杂乱的很好方式
我们可以看到光标在区段之间切换时 UISegmentedControl 是如何隐藏分隔符的 这样看起来更干净、更整洁
要协调动画 只需实施 UIPointerInteraction- Delegates 的 willEnter 和 willExitRegion 方法 并将动画附加到提供的属性动画对象
在本例中 我们将在光标进入区域时 淡出分隔符视图 在退出时淡入分隔符视图
有关更多指导方针和改善建议的内容 请查看 Human Interface Guidelines 和开发者说明文档 另外 请查看与此视频相关的示例 因为有一些很好的示例供你尝试
牢记这些简约的指导方针 构建具有一流光标体验的 iPad apps 想要获得更原生的外观和感觉 最好使用更高级的 API 给控件和自定义用户界面添加光标效果 以使其感觉更灵敏 最后 采取一些小步骤来完善执行 并为你的用户界面注入惊喜和快乐 感谢观看 我很期待使用你将要构建的 所有令人惊叹的 光标功能的 app 了
-
-
6:04 - UIButton Pointer Effects
// Enable the button's built-in pointer interaction. myButton.isPointerInteractionEnabled = true // Customize the default interaction effect. myButton.pointerStyleProvider = { button, proposedEffect, proposedShape -> UIPointerStyle? in // In this example, we'll switch to using the .lift effect by creating a new // UIPointerEffect with the .lift type using the proposedEffect's preview. return UIPointerStyle(effect: .lift(proposedEffect.preview), shape: proposedShape) }
-
7:05 - Pointer Content Effect
// Create a UIPointerStyle that applies the .highlight effect. // Outset the view's frame so the pointer shape has some generous padding around the view's contents. // Note that this frame must be in the provided UITargetedPreview's container's coordinate space. // In the majority of cases (where the preview doesn't have a custom container), this is just the view's superview. let rect = myView.frame.insetBy(dx: -8.0, dy: -4.0) let preview = UITargetedPreview(view: myView) return UIPointerStyle(effect: .highlight(preview), shape: .roundedRect(rect))
-
8:02 - Pointer Shape Customization
// Create a UIPointerStyle that changes the pointer into a vertical beam. let beamLength = myFont.lineHeight return UIPointerStyle(shape: .verticalBeam(length: beamLength), constrainedAxes: .vertical)
-
21:31 - UIPointerInteraction Region Entrance Animation
func pointerInteraction(_ interaction: UIPointerInteraction, willEnter region: UIPointerRegion, animator: UIPointerInteractionAnimating) { // Fade out separator when entering region. animator.addAnimations { self.separatorView.alpha = 0.0 } }
-
21:51 - UIPointerInteraction Region Exit Animation
func pointerInteraction(_ interaction: UIPointerInteraction, willExit region: UIPointerRegion, animator: UIPointerInteractionAnimating) { // Fade separator back in when exiting region. animator.addAnimations { self.separatorView.alpha = 1.0 } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。