在 App 設計中,進度條(Progress Bar)或其他類似的指示器在執行比較耗時的任務時,能發揮重要的作用。透過顯示進度讓使用者大概了解完成操作需要多長時間,令用戶體驗得以提升。
SwiftUI 框架提供了一個內置組件,稱為 ProgressView
,供開發人員展示進度條或圓形指示器來顯示長時間運行操作的進度,例如下載文件或上傳數據到服務器。
ProgressView
的預設外觀簡單,可能不符合您的 App 設計和主題。這就是 ProgressViewStyle
協議發揮作用的地方。您可以使用 ProgressViewStyle
協議為 ProgressView
組件創建與您的App設計和主題相匹配的自定義樣式。
在本教學中,我將介紹 ProgressView
的基礎知識,並向您展示如何使用 ProgressViewStyle
自定義進度視圖的外觀。
ProgressView 基礎操作
ProgressView
組件非常容易使用。在您的 SwiftUI App 中,您可以通過編寫以下程式碼來建立進度指示器:
ProgressView()
您還可以選擇性地添加標籤以顯示狀態消息,例如:
ProgressView() {
Text("加載中...")
}
在 iOS 上,進度視圖顯示為圓形指示器。
不確定進度(Indeterminate Progress)和確定進度(Determinate Progress)
ProgressView
組件提供了兩種類型的進度指示器,用於顯示不確定進度(Indeterminate Progress)和確定進度(Determinate Progress)。在前一節中展示的是不確定進度指示器。對於持續執行而未有確實完成時間的任務,例如加載或同步複雜數據,我們通常會使用不確定進度指示器(即是圓形活動指示器)。
在可能的情況下,請使用確定進度指示器。 不確定進度指示器顯示進程正在進行,但它無法幫助使用者估計任務需要多長時間。確定進度指示器可以幫助使用者決定在等待任務完成時是否要做其他事情,是否要在不同的時間重新啟動任務,或者是否要放棄任務。
- 蘋果的人機界面指南
對於具有明確時間長度的任務(例如文件下載),可以使用確定進度指示器。在 iOS 上,確定進度指示器是以進度條的形式呈現。要實現這一點,您只需要使用當前進度值建立 ProgressView
。以下是一個示例:
ProgressView(value: 0.3)
在預設的情況下,總值為 1.0。您可以提供介於 0.0 和 1.0 之間的值,其中 1.0 即表示 100% 完成。如果您必須使用不同範圍和不同總值,則可以使用另一個初始化器編寫程式碼:
ProgressView(value: 30, total: 100)
這兩行程式碼都顯示了相同的進度指示器,表示已完成 30%。
您還可以選擇性添加一些標籤,以使用 label
和 currentValueLabel
參數顯示狀態消息和當前進度:
ProgressView(value: 0.3,
label: { Text("Processing...") },
currentValueLabel: { Text("30%") })
要更新進度的值,通常會創建一個狀態變數來保存進度的當前值。以下是一個示例程式碼:
struct ContentView: View {
@State private var progressValue = 0.0
var body: some View {
VStack {
ProgressView(value: progressValue, total: 1.0)
.padding()
Button("Start") {
// Start the task
// Update the progress value periodically
for i in 1...5 {
progressValue = Double(i) / 5.0
Thread.sleep(forTimeInterval: 1.0)
}
}
}
}
}
更改進度視圖的顏色和樣式
預設的進度指示器具有簡單的設計和有限的自定義選項。但是,你可以通過應用 tint
修飾器來修改進度條的顏色:
ProgressView(value: 0.3)
.tint(.purple)
確定進度指示器通常顯示為進度條。如果您希望修改其外觀,可以使用 progressViewStyle
修飾器。例如,您可以從預設的 linear
樣式切換至 circular
樣式,如下所示:
ProgressView(value: 0.3, label: { Text("Processing...") }, currentValueLabel: { Text("30%") })
.progressViewStyle(.circular)
這就可以將進度條轉換為圓形指示器。
使用 ProgressViewStyle 作進階設定
雖然進度視圖的預設樣式對大多數 Apps 已經足夠,但您可能還是希望建立與 App 設計相匹配的進度條。如果您想創建更複雜的自定義進度條,就要學習使用 ProgressViewStyle
協議。
ProgressViewStyle
是 SwiftUI 中創建自定義進度指示器的強大工具。通過 ProgressViewStyle
,您可以建立獨特且視覺上吸引人的進度條,完美地配合您的 App 設計和主題。SwiftUI 已有內置幾種樣式直接使用,例如 CircularProgressViewStyle
和 LinearProgressViewStyle
。通過符合 ProgressViewStyle
協議,您可以創建自己的樣式並將其應用於 ProgressView
組件。
為了讓您更好地了解 ProgressViewStyle
,讓我們構建一個像上面所示的自定義進度條。您需要做的是創建一個新的結構(struct),符合 ProgressViewStyle
協議並實現以下所需方法:
@ViewBuilder func makeBody(configuration: Self.Configuration) -> Self.Body
如果您有使用 ButtonStyle
的經驗,ProgressViewStyle
的實作非常類似,因為它遵循相同的模式。
讓我們建立一個名為 BarProgressStyle
的新樣式,如下所示:
struct BarProgressStyle: ProgressViewStyle {
var color: Color = .purple
var height: Double = 20.0
var labelFontStyle: Font = .body
func makeBody(configuration: Configuration) -> some View {
let progress = configuration.fractionCompleted ?? 0.0
GeometryReader { geometry in
VStack(alignment: .leading) {
configuration.label
.font(labelFontStyle)
RoundedRectangle(cornerRadius: 10.0)
.fill(Color(uiColor: .systemGray5))
.frame(height: height)
.frame(width: geometry.size.width)
.overlay(alignment: .leading) {
RoundedRectangle(cornerRadius: 10.0)
.fill(color)
.frame(width: geometry.size.width * progress)
.overlay {
if let currentValueLabel = configuration.currentValueLabel {
currentValueLabel
.font(.headline)
.foregroundColor(.white)
}
}
}
}
}
}
}
這個自定義樣式需要三個參數來配置進度條的顏色、高度和字體樣式。我不會一行一行地解釋 makeBody
方法中的程式碼。簡而言之,我們通過在灰色的另一個 RoundedRectangle
視圖的頂部覆蓋一個紫色的 RoundedRectangle
視圖來實現自己的進度條樣式。
configuration
參數為您提供進度視圖的常見屬性,包括:
fractionCompleted
- 由進度視圖表示的任務完成的部分,從0.0
(尚未開始)到1.0
(完全完成)。label
- 狀態標籤。currentValueLabel
- 顯示當前進度的標籤。
現在,我們已經建立了自己的樣式,您可以通過將 progressViewStyle
修飾器附加到進度視圖來應用它:
ProgressView(value: 0.3, label: { Text("Processing...") }, currentValueLabel: { Text("30%") })
.progressViewStyle(BarProgressStyle(height: 100.0))
作業
了解了 ProgressViewStyle
的基礎知識後,現在是時候將這些知識付諸實踐,創建一個新的自定義樣式了。您可以挑戰自己,試圖建立一個與下面圖片相似的樣式。這作業不僅可以幫助您鞏固所學的知識,還可以訓練實作不同外觀的進度視圖。
總結
從本教學中,我們介紹了如何使用 ProgressView
以顯示耗時任務或操作的進度。在合適的情況下,我們建議盡量使用確定進度指示器,因為它可以為使用者提供更準確的等候時間。
儘管預設進度視圖對大多數 Apps 都已足夠,使用 ProgressViewStyle
協議創建自定義進度視圖還是需要的。通過之前概述的步驟,您現在應該已經掌握了自定義進度視圖的基礎知識。