今天我想和您谈谈SwiftUI中对动态类型的支持。我认为,如果您的应用中没有动态类型支持,就无法创造出色的用户体验。 SwiftUI为任何文本表示形式提供了开箱即用的动态类型,并简化了我们的工作。但是我们仍然需要做一些工作,所以让我们谈谈它。
动态类型基础(Dynamic type)
动态类型功能允许用户选择屏幕上显示的文本内容的大小。它可以帮助需要较大文本以提高可读性的用户。它还适合那些阅读较小文本的人员,使更多信息显示在屏幕上。支持动态类型的应用程序还提供了更一致的阅读体验。
您无需执行任何操作即可在SwiftUI视图中支持动态类型,因为默认情况下,表示文本的所有组件都是多行的。 Apple的《人机界面指南》有一个关于版式的特殊部分,其中提供了常见的文字样式。这些文本样式描述了不同类型的文本内容(例如标题,标题,正文,副标题,标题,脚注)的字体配置。样式在所有应用程序之间共享。尝试尽可能使用这些预定义的文本样式。这是一个如何在SwiftUI中使用HIG定义的文本样式的小示例。
struct PostView: View {
let post: Post
var body: some View {
VStack(alignment: .leading) {
Image(post.image)
Text(post.title)
.font(.headline)
Text(post.time)
.font(.subheadline)
Text(post.body)
.font(.body)
}
}
}
内容大小类别(Content Size category)
在上一段中,我说过SwiftUI开箱即用地支持动态类型,这是事实。但是要支持动态类型,我们需要记住,即使只有两个单词,每个文本也可以是多行。这完全取决于用户定义的字体大小,该字体大小可能会很大。 SwiftUI提供了一个特殊的环境值来描述用户定义的大小类别。让我们来看看如何使用它
import SwiftUI
struct ContentView: View {
@Environment(\.sizeCategory) var sizeCategory
var buttons: some View {
Group {
Button("Action 1") {}
Button("Action 2") {}
}
}
var body: some View {
Group {
if sizeCategory == .accessibilityLarge {
VStack { buttons }
} else {
HStack { buttons }
}
}
}
}
通过使用环境的sizeCategory值,我们可以读取定义的字体大小并决定如何呈现我们的内容。通过使用环境,我们的应用程序将订阅系统设置,并且一旦用户更改了字体大小,我们的视图就会重新加载
让我们继续,为Group组件创建一个扩展,根据用户定义的大小类别将其嵌入到水平或垂直堆栈中。
import SwiftUI
fileprivate struct EmbedInStack: ViewModifier {
private let verticalSizes: [ContentSizeCategory] = [
.accessibilityMedium,
.accessibilityLarge,
.accessibilityExtraLarge,
.accessibilityExtraExtraLarge,
.accessibilityExtraExtraExtraLarge
]
@Environment(\.sizeCategory) var sizeCategory
func body(content: Content) -> some View {
Group {
if verticalSizes.contains(sizeCategory) {
VStack { content }
} else {
HStack { content }
}
}
}
}
extension Group where Content: View {
func embedInStack() -> some View {
modifier(EmbedInStack())
}
}
在上面的示例中,我们使用ViewModifier,它将视图组包装到堆栈中。 ViewModifiers的优点之一是拥有状态或订阅环境值的能力。
ScrollView
短文本为多行的可能性带来了另一个要求。我们需要将根视图嵌入滚动视图,以允许用户在不适合屏幕的情况下滚动内容。它很快就变成样板,这就是为什么我创建了一个特殊扩展以重用此功能的原因
import SwiftUI
extension View {
func embedInScrollView(alignment: Alignment = .center) -> some View {
GeometryReader { proxy in
ScrollView {
self.frame(
minHeight: proxy.size.height,
maxHeight: .infinity,
alignment: alignment
)
}
}
}
}
结论
动态类型是一项非常重要的功能,每个应用程序都应支持它。 SwiftUI开箱即用地支持动态类型,但是需要一些样板。今天,我们学习了如何通过创建特殊的视图扩展来减少它。
推荐
基础文章推荐
经典教程推荐
- onevcat 大神的《SwiftUI 与 Combine 编程》
- 更新近百篇SwiftUI教程《SwiftUI2020教程》
- 帮您突破数据存储难关《SwiftUI vs CoreData数据存储解决方案》
技术源码推荐
推荐文章
CoreData篇
TextField篇
- 《SwiftUI 一篇文章全面掌握TextField文本框 (教程和全部源码)》
- 《SwiftUI实战之TextField风格自定义与formatters》
- 《SwiftUI实战之TextField如何给键盘增加个返回按钮(隐藏键盘)》
- 《SwiftUI 当键盘出现时避免TextField被遮挡自动向上移动》
- 《SwiftUI实战之TextField如何给键盘增加个返回按钮(隐藏键盘)》
JSON文件篇
一篇文章系列
- SwiftUI一篇文章全面掌握List(教程和源码)
- 《SwiftUI 一篇文章全面掌握TextField文本框 (教程和全部源码)》
- SwiftUI一篇文章全面掌握Picker,解决数据选择(教程和源码)
- SwiftUI一篇文章全面掌握Form(教程和源码)
- SwiftUI Color 颜色一篇文章全解决
技术交流
QQ:3365059189
SwiftUI技术交流QQ群:518696470
- 请关注我的专栏icloudend, SwiftUI教程与源码
https://www.jianshu.com/c/7b3e3b671970