我正在嘗試創建下載進度條并在下載完成時同時顯示警報。
對于此任務,我將 AlamoFire 與 SwiftUI 結合使用,因為它使下載變得容易。但是,當我使用帶有 Published 變數的 ProgressView 跟蹤進度時,整個 UI 都會鎖定,我無法弄清楚如何修復它。
我嘗試將 downloadProgress 添加到單獨的 DispatchQueue,但我仍然必須從主執行緒更新 UI,否則 Xcode 會抱怨。
如何測驗附加的示例代碼:
- 點擊“開始下載”
- 等待 ProgressView 移動一點
- 單擊“顯示警報”按鈕
- 嘗試關閉警報,它不會關閉。
我將不勝感激任何幫助。
匯入 SwiftUI 匯入 Alamofire
struct ContentView: View {
@StateObject var viewModel: ViewModel = ViewModel()
@State private var showAlert = false
var body: some View {
VStack {
Button("Show Alert") {
showAlert.toggle()
}
Button("Start download") {
viewModel.startDownload()
}
if viewModel.showProgressView {
ProgressView("Downloading…", value: viewModel.downloadProgress, total: 1.0)
.progressViewStyle(.linear)
}
}
.alert(isPresented: $showAlert) {
Alert(
title: Text("Text"),
dismissButton: .cancel()
)
}
}
}
class ViewModel: ObservableObject {
@Published var currentDownload: DownloadRequest? = nil
@Published var downloadProgress: Double = 0.0
@Published var showProgressView: Bool = false
func startDownload() {
print("Function called!")
showProgressView.toggle()
let queue = DispatchQueue(label: "alamofire", qos: .utility)
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
AF.download("https://speed.hetzner.de/10GB.bin", to: destination)
.downloadProgress(queue: queue) { progress in
print(progress.fractionCompleted)
DispatchQueue.main.async {
self.downloadProgress = progress.fractionCompleted
}
}
.response { response in
print(response)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
uj5u.com熱心網友回復:
這里的問題是您實際上是在向 UI 執行緒發送更新的垃圾郵件,因為 alamofire 經常呼叫提供的閉包downloadProgress(查看控制臺列印)。您需要稍微錯開 AF 進度的更新,以便按下按鈕解除警報可以注冊(在組合中,這將被稱為去抖動)。我在這里所做的是添加了一個小時間計數器,以便它每秒只更新進度1。這些更新之間的時間使 UI 執行緒可以自由地回應點擊等。
import SwiftUI
import Alamofire
struct ContentView: View {
@StateObject var viewModel: ViewModel = ViewModel()
@State private var showAlert = false
var body: some View {
VStack {
Button("Show Alert") {
showAlert.toggle()
}
Button("Start download") {
viewModel.startDownload()
}
if viewModel.showProgressView {
ProgressView("Downloading…", value: viewModel.downloadProgress, total: 1.0)
.progressViewStyle(.linear)
}
}
.alert(isPresented: $showAlert) {
Alert(
title: Text("Text"),
dismissButton: .cancel()
)
}
}
}
class ViewModel: ObservableObject {
@Published var currentDownload: DownloadRequest? = nil
@Published var downloadProgress: Double = 0.0
@Published var showProgressView: Bool = false
func startDownload() {
print("Function called!")
showProgressView.toggle()
let queue = DispatchQueue(label: "net", qos: .userInitiated)
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
var last = Date()
AF.download("https://speed.hetzner.de/10GB.bin", to: destination)
.downloadProgress(queue:queue) { progress in
print(progress.fractionCompleted)
if Date().timeIntervalSince(last) > 1 {
last = Date()
DispatchQueue.main.async {
self.downloadProgress = progress.fractionCompleted
}
}
}
.response { response in
// print(response)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/368983.html
