如何操作。用SwiftUI创建一个自定义的ProgressView
– 4分钟阅读
对于在iOS或MacOS应用程序中创建进度条视图,你可能已经熟悉了UIKit或SwiftUI中的ProgressView元素,也可能知道它缺乏简单的自定义功能。默认实现只是一个充满蓝色的细条。
系统默认的ProgressView
自定义视图修改器,如_背景_、高度 等,将导致改变关于视图的一切,但条本身除外。
它将保持原样–蓝色和普通。
如果你想拥有自己的自定义进度条,你就有两个选择。
- 创建你自己的进度条视图并实现它
- 根据苹果公司提供的ProgressViewStyle协议,创建你的自定义进度条视图样式。
本文将重点讨论后者,尽管你也可以很容易地采用这些代码,通过绑定来扩展它,并拥有你自己的视图而不是样式–只是这根本没有什么意义。
扩展一个现有的协议也应该是首选的方式,因为重新发明轮子很少是一个好主意。
目标
像往常一样,让我们先看看我们最终想实现什么。
我们想要实现的最终进度视图
我们希望有一个更宽的蓝色条,而不是纯色的彩色梯度条。此外,我们希望能够设置一个可选的标签,显示在视图的下方。
协议
苹果为我们提供了一个协议,用于在SwiftUI中创建自定义进程视图样式。ProgressViewStyle。
该协议本身有一个方法要求。
func makeBody(configuration: Self.Configuration) -> Self.Body
这个函数基本上建立了我们的自定义进度视图。在它里面,我们定义了视图的主体和任何属性、样式等–事实上,它和ViewModifier协议的func body(content: Content) -> some View 函数很相似。如果你了解ViewModifier,那么将这些知识运用到样式协议中应该是非常容易的。
样式
创建一个自定义的进度视图样式意味着基本上要定义整个视图主体,而不仅仅是样式。
对于我们的进度视图样式的主体,我们使用了一个ZStack,并将其包裹在一个VStack中,以获得标签的可能性。此外,我们还添加了一些变量,以获得一些自定义选项(如背景、高度等)。
第4-9行是用于定制我们的自定义视图的属性。我们的大多数属性都有默认值,所以只有_笔画_和_填充_是必须的,其余的都是可选的。
在ZStack里面,我们放置了一个GeometryReader来动态地读取视图的宽度,然后我们根据进度视图的当前值,将其用于封闭的矩形宽度。如果用户旋转屏幕或改变视图的分辨率,进度条的状态应该是一样的,只是按比例调整到新的宽度。
进度条的当前值可以从makeBody函数中的给定配置对象中读取。_configuration.fractionCompleted的_值代表了当前整体工作完成的分数,是一个从0到1的Double值。
实现
让我们来看看如何实现我们的自定义进度条。我们将使用一个定义进度条状态的Slider视图来代替进度条的静态值。有了它,我们可以动态地改变进度条。
为了保持简单,我们只用ContentView.swift文件来实现–在现实生活中,把它分成不同的文件可能会更好。
ContentView.swift
第一行(3-36)是我们在前一节中的进度条样式。
第39-75行是实现本身。像往常一样,它应该是非常直接的。首先,我们为值、输入状态(用于我们的滑块)和我们想用于进度条的梯度定义了一些状态变量。
在第59-61行中,你可以看到ProgressView的实现,其中附有我们的自定义样式和一些垂直填充。没有太多花哨的东西…
如果我们运行代码并转动滑块手柄,我们的进度条就会和我们上面看到的一模一样。这个方法应该给了我们一些创建自定义进度条的基本概念,所以你现在可以很容易地创建你自己的进度条,或者只是从这里取用代码并加以扩展。