SwiftUI中的动态类型Dynamic Type

今天我想和您谈谈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开箱即用地支持动态类型,但是需要一些样板。今天,我们学习了如何通过创建特殊的视图扩展来减少它。

推荐

基础文章推荐

  • 《SwiftUI是什么,听听大牛们如何说》

经典教程推荐

  • onevcat 大神的《SwiftUI 与 Combine 编程》
  • 更新近百篇SwiftUI教程《SwiftUI2020教程》
  • 帮您突破数据存储难关《SwiftUI vs CoreData数据存储解决方案》

技术源码推荐

推荐文章

CoreData篇

  • SwiftUI数据存储之做个笔记App 新增与查询(CoreData)
  • SwiftUI进阶之存储用户状态实现登录与登出
  • SwiftUI 数据之List显示Sqlite数据库内容(2020年教程)

TextField篇

  • 《SwiftUI 一篇文章全面掌握TextField文本框 (教程和全部源码)》
  • 《SwiftUI实战之TextField风格自定义与formatters》
  • 《SwiftUI实战之TextField如何给键盘增加个返回按钮(隐藏键盘)》
  • 《SwiftUI 当键盘出现时避免TextField被遮挡自动向上移动》
  • 《SwiftUI实战之TextField如何给键盘增加个返回按钮(隐藏键盘)》

JSON文件篇

  • SwiftUI JSON文件下载、存储、解析和展示(代码大全)

一篇文章系列

  • SwiftUI一篇文章全面掌握List(教程和源码)
  • 《SwiftUI 一篇文章全面掌握TextField文本框 (教程和全部源码)》
  • SwiftUI一篇文章全面掌握Picker,解决数据选择(教程和源码)
  • SwiftUI一篇文章全面掌握Form(教程和源码)
  • SwiftUI Color 颜色一篇文章全解决

技术交流

QQ:3365059189
SwiftUI技术交流QQ群:518696470

  • 请关注我的专栏icloudend, SwiftUI教程与源码
    https://www.jianshu.com/c/7b3e3b671970

你可能感兴趣的:(SwiftUI中的动态类型Dynamic Type)