【问题标题】:ProgressView Not UpdatingProgressView 未更新
【发布时间】:2021-07-10 12:35:17
【问题描述】:

我正在尝试在将图像上传到 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()
    }
}

}

【问题讨论】:

  • 您是否尝试过使用@State var userManager
  • 你检查过self是否为nil吗?
  • 尝试在userManager 上的@EnvironmentObject 上使用@ObservedObject,然后设置一个实例。例如。 @ObservedObject var userManager = UserManager() 然后将其作为 ViewModel 引用。如果您需要它作为@Environment,请考虑将其更改为单例。
  • @Todd 我刚试了一下,没用,谢谢。
  • @George_E 是的。也许我不清楚,但我能够打印进度。例如。 onAppear { print(userManager.taskProgress) } 只是没有更新的进度视图。

标签: swift swiftui firebase-storage


【解决方案1】:

从 cmets 中,我们推断它是一个不同的 UserManager 实例。下面是一个如何将 same 实例传递给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()
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多