swift - ProgressView 未更新
问题描述
将图像上传到 Firebase 存储时,我正在尝试观察进度。控制台中的进度正在更新,但是我的 ProgressView 没有更新。其他一切似乎都按预期工作。知道我做错了什么吗?
class UserManager: ObservableObject {
@Published var taskProgress: Float = 0.0
let user = Auth.auth().currentUser
func uploadProfilePicture(image: UIImage) {
let uploadRef = FirebaseReferenceManager.storage.reference(withPath: "profile/\(user!.uid)")
guard let imageData = image.jpegData(compressionQuality: 0.75) else {
return
}
let uploadMetaData = StorageMetadata.init()
uploadMetaData.contentType = "image/jpeg"
let taskReference = uploadRef.putData(imageData, metadata: uploadMetaData) { (downloadMetaData, error) in
if let error = error {
print(error.localizedDescription)
return
} else {
print("Successfully Uploaded Profile Picture to Firebase Storage")
let downloadRef = FirebaseReferenceManager.storage.reference(withPath: "profile/\(self.user!.uid)")
downloadRef.downloadURL { (url, error) in
if let error = error {
print(error.localizedDescription)
return
}
FirebaseReferenceManager.root.collection(FirebaseKeys.CollectionPath.users).document(self.user!.uid).setData([FirebaseKeys.UsersFieldPath.photoURL : url!.absoluteString], merge: true)
}
}
}
taskReference.observe(.progress) { [weak self] (snapshot) in
DispatchQueue.main.async {
guard let pctThere = snapshot.progress?.fractionCompleted else {return}
print(pctThere)
self?.taskProgress = Float(pctThere)
}
}
taskReference.resume()
}
}
在我看来,我把以下
@EnvironmentObject var userManager: UserManager
ProgressView(value: userManager.taskProgress).progressViewStyle(LinearProgressViewStyle())
以下是类的初始化方式:
struct SwiftUIView: View {
@StateObject var userManager = UserManager()
var body: some View {
TabView {
HomeView().tabItem {
Image("home")
Text("Home")
}
SearchView().tabItem {
Image("search")
Text("Search")
}
DiscoverView().tabItem {
Image("discover")
Text("Discover")
}
OrdersView().tabItem {
Image("calendar")
Text("Orders")
}
InboxView().tabItem {
Image("inbox")
Text("Inbox")
}
}
.environmentObject(userManager)
}
}
然后我使用
@EnvironmentObject var userManager: UserManager
这里是调用 uploadProfilePicture() 的地方:
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
@Binding var selectedImage: UIImage
@Environment(\.presentationMode) private var presentationMode
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.delegate = context.coordinator
imagePicker.allowsEditing = true
imagePicker.sourceType = sourceType
return imagePicker
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let parent: ImagePicker
@ObservedObject private var userManager = UserManager()
init(_ parent: ImagePicker) {
self.parent = parent
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.editedImage] as? UIImage {
parent.selectedImage = image
userManager.uploadProfilePicture(image: image)
}
parent.presentationMode.wrappedValue.dismiss()
}
}
}
解决方案
从评论中,我们推断这是一个不同的UserManager
例子。这是一个如何将相同实例传递给的示例Coordinator
(这是假设 ImagePicker 存在于@EnvironmentObject var userManager: UserManager
可用的环境中)。
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
@Binding var selectedImage: UIImage
@Environment(\.presentationMode) private var presentationMode
@EnvironmentObject private var userManager: UserManager //<-- Here
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.delegate = context.coordinator
imagePicker.allowsEditing = true
imagePicker.sourceType = sourceType
return imagePicker
}
func makeCoordinator() -> Coordinator {
Coordinator(self, userManager: userManager) //<-- Here
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
let parent: ImagePicker
let userManager: UserManager
init(_ parent: ImagePicker, userManager: UserManager) { //<-- Here
self.parent = parent
self.userManager = userManager //<-- Here
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[.editedImage] as? UIImage {
parent.selectedImage = image
userManager.uploadProfilePicture(image: image)
}
parent.presentationMode.wrappedValue.dismiss()
}
}
}
推荐阅读
- android - 如果只有一个意图,如何防止 Intent.createChooser 自动使用 Intent?
- jquery - 如何通过输入值增加数字?
- thymeleaf - 可以在angular8组件中加载springboot yaml属性
- python - 下面代码中 (qs | qs1) 的含义是什么?
- sql - 如何仅按时间部分比较日期时间列
- php - 高级自定义字段引导滑块活动状态
- windows - 无法映射 LAlt + autohotkey 中的任何键
- url-rewriting - 路由 2 Angular 应用程序,任何 URL 重写?
- json - com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造`java.time.Instant`的实例(没有创建者,如默认构造):
- reactjs - 如何为标记添加默认选项