gpt4 book ai didi

swiftui - 如何在 SwiftUI 中传递进度值(也许使用组合)?

转载 作者:行者123 更新时间:2023-12-02 19:40:08 25 4
gpt4 key购买 nike

我刚开始学习SwiftUI,但没有时间Combine。我对此不太了解。如何在ProgressView中向下载进度传递一个值。如何配置 ODRManager 以及如何在下载过程中传输该值,不是 0 并立即为 1,而是 0.0 ... 0.1.0.2 ... 0.8,0.9,1.0我想知道不同的方法和手段仅 SwiftUI,并使用组合或其他方法。

非常感谢。

SwiftUI 代码

import SwiftUI

struct ProgressView: View {

@Binding var value: Float

var body: some View {
GeometryReader { geometry in
ZStack(alignment: .leading) {
Rectangle()
.frame(width: geometry.size.width, height: geometry.size.height)
.opacity(0.3)
.foregroundColor(.gray)

Rectangle()
.frame(width: min(CGFloat(self.value) * geometry.size.width, geometry.size.width), height: geometry.size.height)
.foregroundColor(.blue)
.animation(.linear)
}.cornerRadius(45.0)
}
}
}

struct ContentView: View {

@State var progressValue: Float = 0.0

var body: some View {
VStack {
Button(action: { //here is the function to download from ondemand }) {
Text("Download")
.padding(.init(top: 10, leading: 30, bottom: 10, trailing: 30))
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(14)

}
.padding(.bottom, 30)

ProgressView(value: $progressValue)
.environmentObject(self.manager)
.frame(width: 250, height: 20)
}
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()

}
}

OnDemand 管理器代码

class ODRManager: NSObject {
var resourceRequest : NSBundleResourceRequest?
var progress:Float = 0.0

func fetchODRResourceWithName(fileName: String) {
guard self.resourceRequest == nil else {return}
self.resourceRequest = NSBundleResourceRequest(tags: [fileName])
progress = Float((resourceRequest?.progress.fractionCompleted)!)
self.resourceRequest!.progress.addObserver(self, forKeyPath: "fractionCompleted", options: .new, context: nil)
self.resourceRequest?.conditionallyBeginAccessingResources(completionHandler: { (resourceAvailable) in
if !resourceAvailable {
self.resourceRequest!.beginAccessingResources { err in
guard err == nil else {
print(err as Any)
return
}
print("downloading..")
}
} else {
print("was downloaded")
}
})
}

func stopDownloadingFile() {
guard self.resourceRequest != nil else {
return
}
self.resourceRequest!.endAccessingResources()
self.resourceRequest!.progress.removeObserver(self, forKeyPath: "fractionCompleted")
self.resourceRequest!.progress.cancel()
self.resourceRequest = nil
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "fractionCompleted" {
DispatchQueue.main.async { [weak self] in
self.progress = Float((self?.resourceRequest!.progress.fractionCompleted)!)
}
}
}
}

最佳答案

目前尚不清楚 ODRManagerContentView 之间的关系,但我建议在它们之间引入一些中间模型(以避免紧密耦合),例如

class ProgressItem: ObservableObject {
@Published var progressValue: Float = .zero
}

因此将 ProgressItem 的相同实例传递到

class ODRManager: NSObject {
var resourceRequest : NSBundleResourceRequest?
var progress: ProgressItem? = nil // set up in init
...

struct ContentView: View {
@ObservedObject var progress = ProgressItem() // as variant
...
ProgressView(value: $progress.progressValue)
.frame(width: 250, height: 20)

您只能有条件地加入引擎和 UI,彼此不依赖。

关于swiftui - 如何在 SwiftUI 中传递进度值(也许使用组合)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60377801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com