大多数浏览器和
Developer App 均支持流媒体播放。
-
认识 UIKit 按钮系统
每个 app 都使用按钮。iOS 15 中,您可已通过更新样式创建与您的界面轻松搭配的华丽按钮。我们将探索能更加轻松地创建不同类型按钮的功能,学习如何提供更丰富的交互,以及发现如何在使用 Mac Catalyst 时获得强大按钮。
资源
相关视频
WWDC21
-
下载
♪♪ 嗨 我是大卫邓肯 和我的同事 埃里克杜迪亚克 我们将讨论 iOS 15中UIKit帮你改善 按钮的各种方法
不起眼的按钮 大大小小的应用程序的主要组成要素 按钮可能是 请求用户输入的最常见方式 按钮有多种形式:大的和小的 带有图像、文本或两者皆有 有背景或没有背景 像彩虹一样可能拥有各种颜色 让我们先关注一些特定的风格
在iOS15中 UIKit现在提供了 这四种基本样式 在你知道和喜爱的素色样式中 新增的是 新的灰色、着色和填充样式
但是UIKit不仅仅让 iOS15中的按钮更具现代风格 这也让它们变得更加强大 现在默认支持动态字体 按钮系统内置多行文本支持
通过更好地支持所有辅助功能 以及生成按钮来增强辅助功能 在默认情况下更容易访问 有了所有这些新功能 按钮的可定制性 比以往任何时候都高 因此你可以准确地获得所需的样式 有了这个基础 让我们认识一下 UIButtonConfiguration 新按钮系统的入口点
欢迎来到ButtonEmporium 各种形状和尺寸纽扣的主要提供者
ButtonEmporium 总是希望拥有最好的按钮 所以让我们更新应用以采用 UIButtonConfiguration… 从最重要的登录按钮开始
目前 该应用程序使用此代码 生成一个登录按钮 生成一个带有登录标志的 普通系统按钮
但这是一个非常重要的按钮 所以让我们使用新的填充样式 让它更加突出
我们完成了! 使用UIButtonConfiguration 很容易上手 因为UIButton 会自动集成标题和图像 在你提供的配置上 使用现有API进行设置 从而轻松更新按钮的样式 无需立即更新所有代码 但是当你准备好更新你的代码时 UIButtonConfiguration 不仅是有样式而已 接下来让我们来看看
这是我们当前的 “添加到购物车”按钮
现在这是一个非常基本的按钮 但我们将利用 UIButtonConfiguration 提供的新功能 加速按钮购买体验
首先 我们将使用着色样式 因为它可以补充我们的其他按钮 我们首先创建一个着色按钮配置 设置它的标题 匹配我们之前配置按钮的方式
接下来 我们用 我们填写的配置来创建按钮
这已经是一个很大的改进 但让我们把它放在首位 我们要做的下一个改进是 向按钮添加图像 使其作用能够一目了然
我们的设计师希望图像 在尾部的位置 所以在旁边设置了 image属性 我们还设置了 imagePlacement属性 将图像准确放置在我们想要的位置
但是我们还想向 新的“添加到购物车”按钮 添加另外两个功能
第一个是预览 当你订购多件商品时会发生什么 这将使用 UIButtonConfiguration的 subtitle功能
第二种是在按下按钮时 从轮廓图像切换到填充版本
为此 我们需要在适当的时候 更新image属性
为了在这些更改发生时 正确更新按钮 我们将添加一个 configurationUpdateHandler
当按钮需要更新时 将调用configurationUpdateHandler 允许你进行集中更改
通常你会改变按钮的配置 所以它通常 通过获取起始配置开始 并以设置更改的配置结束
在这里 我们从按钮的现有配置开始 但你也可以轻松创建一个新配置 并填写它的所有参数
首先让我们为按钮 设置正确的图像 当按钮被按下时 isHighlighted会返回true 我们设置购物车符号的填充版本
否则 我们使用只有外轮廓的版本
由于isHighlighted 是UIButton的一个状态 所以自动排列 用于在该值更改时调用 configurationUpdateHandler
接下来 我们在 itemQuantityDescription 更改时更新副标题 但是itemQuantityDescription 不是UIButton的属性 我们如何安排在值改变时 调用configuration UpdateHandler呢?
当客户更改要购买的按钮数量时 应用程序会更新 itemQuantityDescription
为了确保添加到购物车按钮也更新 我们的didSet处理程序调用 setNeedsUpdateConfiguration 依次安排配置UpdateHandler 被调用并触发按钮的更新
在ButtonEmporium 我们从未遇到过我们不喜欢的按钮 使用UIButtonConfiguration 有很多值得喜欢的地方
在我们更新下一个按钮之前 让我们快速介绍一些其他功能
按钮现在可以显示活动指示器 从而可以轻松提供 应用程序繁忙的反馈
只需在你的按钮配置中将 showsActivityIndicator 设置为true 我们就会显示指示器 必要时更换图像
调整按钮布局的各个方面 很简单 给你更多的控制 关于内容在按钮中的定位方式 在这里你可以看到 contentInsets 在按钮边缘保留空间 和imagePadding和 titlePadding允许我们 增加这些元素之间的空间
虽然UIKit会自动布局这些组件 你可以控制标题彼此的对齐方式 以及按钮的内容如何 在内容区域内对齐
语义样式使创建具有 内聚样式的按钮变得简单 无需深入研究细节
从一个简单的填充按钮开始 我们配置baseBackgroundColor baseForegroundColor、cornerStyle 和buttonSize 生成自定义按钮 并自动获取主题状态 例如按下和禁用 无需任何额外的成本
但即使有很多自动化 进行详细的定制仍然很容易 有些时候 你必须精准控制你所需的样式 就像我们最重要的结账按钮一样
为确保Button Emporium 客户能够轻松获得钮扣 结账按钮需要很大 很容易找到
要构建它 我们将从填充样式开始 将其大小设置为大 并填写其图片和标题
当点击按钮时 我们开始处理购物车 并希望显示一个活动指示器
要启用此功能 我们添加一个 configurationUpdateHandler 来管理showsActivityIndicator 属性的配置
和以前一样 对isCartBusy 属性的更改将调用 setNeedsUpdateConfiguration 以确保活动指示器 根据需要打开和关闭
虽然蓝色很好 但我们希望 确保给人留下深刻印象
所以为了确保我们 将精确的颜色用于背景 让我们设置 UIButtonConfiguration的 UIBackgroundConfiguration 的背景颜色 这样更好
既然我们已经讨论了 UIButtonConfiguration 如何让你的按钮看起来比以往更好 我会把它交给埃里克 来谈谈按钮可以做的其他新事情 谢谢 大卫 现在我们已经了解了 如何自定义按钮的外观 接下来让我们了解一下 如何自定义按钮的功能 大多数按钮只是简单的按压按钮 但有时按钮需要一些额外的行为 我们要了解的第一个是切换按钮
这些按钮保留了 UIControl的选定状态 每次按下按钮时 它们都会自动打开和关闭它
它也可以根据需要 以编程方式进行更改
除了打开和关闭状态的内置样式 我们可以利用 UIButtonConfiguration 来自定义这些开和关状态的呈现
iOS上切换按钮的概念 并不新鲜 你可能已经注意到一些按钮 例如音乐应用程序中的歌词按钮
它可以像这样在播放器中 打开和关闭歌词
在功能上 这就像UISwitch 但它在UI中节省了一些空间 它更适合应用程序的设计
切换按钮也可以处理 UIBarButtonItems 就像日历中的这个一样
在顶部栏中 可以启用 和禁用日期详细信息
按下它会切换详细信息的显示
在这种情况下 UIBarButtonItem上 有一个新的selected属性 可以读取或设置 对于所选状态 现在让我们更新Button Emporium 以采用切换按钮
我们的应用程序让我们可以 浏览想要购买的纽扣种类 但是在浏览时 我只想细读当前的库存 在这里 我们添加了一个切换按钮 用来在全部货品 和现有库存货品之间切换 这是切换按钮的一个很好的用途 一个优点是 因为它是一个按钮 文本标签是它的一部分 让这里正在切换的内容非常清楚
那让我们来看看我们是如何做到的 在这里 我们有设置按钮的基础 为了使它成为一个切换按钮 我们只需将 changesSelectionAsPrimaryAction 设置为true 现在它是一个切换按钮 就是这样
我们还可以设置选定状态 以匹配我们的内部模型
现在 我们可能想要一些 更复杂的东西 而不是只有两种状态的开和关 对于可以有更多选项切换的按钮 我们可以使用弹出按钮 弹出按钮是下拉按钮的近亲 在iOS中已经存在 按下时会显示一个菜单 弹出按钮更进一步 并确保选择了一个 且仅一个菜单元素
他们还将当前选项 显示为标题和图像 构建弹出按钮其实就是 构建一个下拉按钮的扩展 对于那些 为按钮分配了一个菜单 为了使菜单成为默认操作 将showsMenuAsPrimaryAction 属性设置为true
弹出按钮更进一步 只需打开 changesSelectionAsPrimaryAction 属性即可 这就是全部 它们像UISegmentedControl 一样工作 但在有更多选择时 会比分段控件更适合 它们对于选择具有 固有层次结构的情况也很有用
如今有一些关于这种按钮样式的范例 例如 电话应用程序使用弹出按钮 在SIM卡之间切换以拨出电话
这里的按钮显示了一个菜单 选择次要选项可以切换线路 结果 按钮更新为 新的拨出线路 标签和图像已更新 以显示新选择
同样 我们在Button Emporium中 也有一些用途 当我们浏览按钮时 我们会看到 一些有多种颜色的按钮 颜色的数量是固定的一组 可供选择 但对于分段控件 可能太大了 但它也足够小到 我们希望能以行内的方式来改变它
这是弹出按钮的一个很好的用途 因为我们希望选项就是按钮的标题 然后我们可以展示所有的颜色选项
在新的选项上 我们的应用程序 可以只更新颜色选择
让我们研究一下代码 在这里 我们实际上有要制作的代码 一个简单的下拉菜单 我们可以更新
就像切换按钮一样 我们将 changesSelectionAsPrimaryAction 切换为true 现在它是一个弹出按钮
如果我们想让特定颜色成为默认选项 而不仅仅是第一种颜色 在列表中 我们可以在 设置菜单时将其预先分配为“on”
这将使其成为默认选项
我们可以通过 询问按钮的菜单来检查选择 对于currentSelectedElements 它总是只有一个元素
如果我们需要在代码中 设置一个新的 我们可以改变 来自按钮菜单属性的元素状态
也可以在Interface Builder中 创建弹出按钮 但在这种情况下 我们将要检索 来自服务器的动态颜色 而不是使用固定列表 所以我们将在代码中进行 了解有关使用新按钮系统的更多信息 和带有Interface Builder的 按钮类型 请查看《构建具有风格的界面》视频
这些新按钮类型的最棒之处 是它们可以自动在 Mac Catalyst上工作 Mac用户希望按钮 具有特定的外观和行为 包括下拉、弹出和切换按钮 使用这些iOS按钮 它们会自动更新到Mac版本
所以这里我们从iPad 应用程序中选择了一些按钮 就像在整个演示中一直使用的那样 其中包括默认的无边框按钮 和一些使用新配置的按钮 以及弹出和下拉按钮
在这里 它们在 Mac Catalyst上没有手动更改 正如经验丰富的Mac用户 所期望的那样 我们得到标准的边框按钮 包括用于下拉和弹出按钮的 Mac指示器
然而 在某些情况下 iPad 按钮的额外自定义可能更合适 即使对于Mac应用程序 为此 按钮支持将行为风格 从默认的自动更改为iPad
这对于应用程序中非常突出的 自定义按钮很有用 例如结账按钮 我们之前做的 有关构建和自定义Mac Catalyst 应用程序的更多信息 请查看《Mac Catalyst的新功能》视频
正如你在弹出按钮范例中 所注意到的那样 大部分功能都建立在UIMenu的 新功能和现有功能之上
UIMenu与UIButton 和UIBarButtonItem搭配得非常好 可以进行很多很棒的交互 我们已经探索了如何调整按钮的行为 创建弹出按钮和下拉按钮 在iOS和iPadOS上 这些行为独立于视觉自定义 因此你可以轻松地将它们与 UIButtonConfiguration结合 以创建许多不同的按钮样式
这些按钮还受益于菜单的改进 例如菜单项的功能 有副标题以提高清晰度
最重要的是 iOS和iPadOS上的 子菜单导航也得到了改进 允许在菜单中创建层次结构 在某些情况下 你可能需要子菜单 一个下拉按钮的行为 作为单选菜单本身 如果你有“排序”菜单 这会很有用 例如 在操作菜单中 一些新的菜单改进 使创建更容易
这是一个自定义下拉栏按钮项 在我们的代码中使用子菜单
它有几个操作 然后是一个用于 对结果进行排序的子菜单 而不是手动打开和关闭 该子菜单中的菜单项 我们只是要指出 这个子菜单是 我们创建时的单选 现在它获得相同的自动选择行为 弹出按钮只是在子菜单内 只允许一个被选中的元素 当用户点击它时 被选中的元素将被更新
它可以以完全相同的方式 在代码中更新或访问 正如我们之前对弹出菜单所做的那样
如果菜单 有自己的子菜单 一次只能选择 整个子树中的一个元素 并且selectedElements属性 包括子菜单中的选择 使得访问 就像我们没有子菜单一样简单
这就是如何在你的应用程序中 制作更好的按钮 向按钮添加配置 以更好地控制样式 解锁更丰富的样式 同时仍与平台保持一致
还探索替换现有选择器界面的方法 或带有弹出或切换按钮的控件 以获得更流畅的交互
通过这些更改 你可能会发现 可以删除或简化的UIButton子类
因为系统可以更好地理解你的按钮 你会自动变得更擅于 Mac Catalyst的转换 感谢你加入我们 希望你享受 对按钮世界的深入探讨 [轻快音乐]
-
-
2:13 - Creating a button with a configuration
// Create the Sign In button let signInButton = UIButton(type: .system) signInButton.configuration = .filled() signInButton.setTitle("Sign In", for: [])
-
3:20 - Customizing a button configuration
// Create the Add to Cart button var config = UIButton.Configuration.tinted() config.title = "Add to Cart" config.image = UIImage(systemName: "cart.badge.plus") config.imagePlacement = .trailing addToCartButton = UIButton(configuration: config, primaryAction: …)
-
4:45 - Customizing a button with a configuration update handler
// Customize image and subtitle with a configurationUpdateHandler addToCartButton.configurationUpdateHandler = { [unowned self] button in var config = button.configuration config?.image = button.isHighlighted ? UIImage(systemName: "cart.fill.badge.plus") : UIImage(systemName: "cart.badge.plus") config?.subtitle = self.itemQuantityDescription button.configuration = config }
-
5:59 - Indicating a configuration needs an update
// Update addToCartButton when itemQuantityDescription changes private var itemQuantityDescription: String? { didSet { addToCartButton.setNeedsUpdateConfiguration() } }
-
8:26 - A completely customized button
// Configure the button background var config = UIButton.Configuration.filled() config.buttonSize = .large config.image = UIImage(systemName: "cart.fill") config.title = "Checkout" config.background.backgroundColor = .buttonEmporium let checkoutButton = UIButton(configuration: config primaryAction: …) addToCartButton.configurationUpdateHandler = { [unowned self] button in var config = button.configuration config?.showsActivityIndicator = self.isCartBusy button.configuration = config }
-
11:56 - Creating a toggle button
// Toggle button // UIAction setup let stockToggleAction = UIAction(title: "In Stock Only") { _ in toggleStock() } // The button let button = UIButton(primaryAction: stockToggleAction) button.changesSelectionAsPrimaryAction = true // Initial state button.isSelected = showingOnlyInStock()
-
14:30 - Creating a pop-up button
// Pop-up button let colorClosure = { (action: UIAction) in updateColor(action.title) } let button = UIButton(primaryAction: nil) button.menu = UIMenu(children: [ UIAction(title: "Bondi Blue", handler: colorClosure), UIAction(title: "Flower Power", state: .on, handler: colorClosure) ]) button.showsMenuAsPrimaryAction = true button.changesSelectionAsPrimaryAction = true // Update to the currently set one updateColor(button.menu?.selectedElements.first?.title) // Update the selection (button.menu?.children[selectedColorIndex()] as? UIAction)?.state = .on
-
18:18 - Creating a custom single selection menu
// Single selection menu // The sort menu let sortMenu = UIMenu(title: "Sort By", options: .singleSelection, children: [ UIAction(title: "Title", handler: sortClosure), UIAction(title: "Date", handler: sortClosure), UIAction(title: "Size", handler: sortClosure) ]) // The top menu let topMenu = UIMenu(children: [ UIAction(title: "Refresh", handler: refreshClosure), UIAction(title: "Account", handler: accountClosure), sortMenu ]) let sortSelectionButton = UIBarButtonItem(primaryAction: nil, menu: topMenu) updateSorting(sortSelectionButton.menu?.selectedElements.first)
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。