发出从 firebase 调用信息以设置按钮标题的问题

Posted

技术标签:

【中文标题】发出从 firebase 调用信息以设置按钮标题的问题【英文标题】:issues calling information from firebase to set button titles 【发布时间】:2020-02-27 22:07:48 【问题描述】:

我正在尝试从 firebase 检索一些信息,以便设置按钮的某些功能。我能够正确设置标题和背景颜色。但是,按钮操作是相同的。

在我看来,用户单击将信息保存到 Firebase 的按钮,然后按钮标题和背景会发生变化。当用户单击按钮时,启动的代码以 handleConfirm 开头。此代码运行完美,将所有数据保存到 firebase,等等。

    @objc func handleConfirm() 
           let workUser = self.workerUser
           let username = workUser?.name
           let post = notification?.poster
           let jobTitle = post?.category


           let alert = UIAlertController(title: "Ready? ",message:" Are you ready to complete the job \(jobTitle!) for \(username!) ?", preferredStyle: UIAlertController.Style.alert)

           let cancelButton = UIAlertAction(title: "Cancel", style: .default, handler: (_ action: UIAlertAction) -> Void in
                  print("you pressed Yes, please button")
              )

           let continueButton = UIAlertAction(title: "Get to Work!", style: .default, handler: (_ action: UIAlertAction) -> Void in
            self.fetchJobProgress()
            self.updateNSaveJobProgress()
            let hud = JGProgressHUD(style: .dark)
                  hud.textLabel.text = "Confirming!"
                    hud.show(in: self.view)


            hud.dismiss()
              )

           continueButton.setValue(GREEN_Theme, forKey: "titleTextColor")
           cancelButton.setValue(UIColor.red, forKey: "titleTextColor")
           alert.addAction(cancelButton)
           alert.addAction(continueButton)
           self.present(alert, animated: true, completion: nil)


func updateNSaveJobProgress() 
    let workUser = self.workerUser
    let uid = Auth.auth().currentUser?.uid
    let workerId = workUser?.uid
    let address = workerUser?.address
     let createDate = Int(NSDate().timeIntervalSince1970)

    Database.database().reference().child("users").child(uid!).observeSingleEvent(of: .value, with:  (snapshot) in
        guard let dictionary = snapshot.value as? [String : Any] else  return 
        let user = User(dictionary: dictionary as [String : AnyObject])
        workUser?.uid = snapshot.key

        let docData: [String: Any] = ["workerId": uid!,
                                      "creationDate": createDate,
                                      "fromId" : workerId!,
                                      "location": address,
                                      "type": 2,
                                      "checked": 0,]

        self.postJobNotificationsIntoDatabseWithUID(uid: workerId!, values: docData as [String : AnyObject])
        self.updateUserDataIntoDatabseWithUID(uid: uid!, values: docData as [String : AnyObject])
        JOB_POST_REF.child(uid!).child("progress?").setValue(2)

     , withCancel:  (err) in
        print("attempting to load information")
        )

        print("Finished saving user info")
        self.dismiss(animated: true, completion: 
            print("Dismissal complete")
        )


    

    private func updateUserDataIntoDatabseWithUID(uid: String, values: [String: AnyObject]) 
        let hud = JGProgressHUD(style: .dark)
        hud.textLabel.text = "Saving"
        hud.show(in: view)

        let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
                    let usersReference = ref.child("workInProgress").child(uid).childByAutoId()
                    usersReference.setValue(values, withCompletionBlock:  (err, ref) in
                    if err != nil 
                        print("error saving data into firebase")
                        return
                    

                    hud.dismiss()
                    self.dismiss(animated: true, completion: nil)
                )

    

 private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject]) 
    let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
        let usersReference = ref.child("notifications").child(uid).childByAutoId()
        usersReference.setValue(values, withCompletionBlock:  (err, ref) in
        if err != nil 
            print("error saving data into firebase")
            return
        
    )

在此之后,我们要调用 fetchJobProgress(),如果用户按下按钮一次或两次,它会设置按钮的视图。注意,在

if type==userNotifications.NotificationType.inProgress.rawValue 

如果我取消注释掉 isuserinteractionenabled = false,用户将无法与按钮交互。为什么?

func fetchJobProgress() 
        let workerId = workerUser?.uid
        let uid = Auth.auth().currentUser?.uid
    Database.database().reference().child("workInProgress").child(uid!).queryOrdered(byChild: "fromId").queryEqual(toValue: workerId).observeSingleEvent(of: .value, with:  (snapshot) in

            guard let dictionary = snapshot.value as? [String : Any] else  return 
        for (_, valueDic) in dictionary 
            guard let dic = valueDic as? [String: Any] else 
                continue
            
            guard let type = dic["type"] as? Int else 
                continue
            

            if type == userNotifications.NotificationType.inProgress.rawValue 

                self.confirmButton.setTitle("In Progress...", for: .normal)
                self.confirmButton.backgroundColor = UIColor.lightGray
                //self.confirmButton.isUserInteractionEnabled = false
            self.confirmButton.addTarget(self, action: #selector(self.handleComplete), for: .touchUpInside)

             else if type == userNotifications.NotificationType.accepted.rawValue 

                self.confirmButton.backgroundColor = GREEN_Theme
                self.confirmButton.addTarget(self, action: #selector(self.handleConfirm), for: .touchUpInside)

              else if type == userNotifications.NotificationType.completed.rawValue 

                self.confirmButton.setTitle("Completed!", for: .normal)
                self.confirmButton.backgroundColor = UIColor.lightGray
                self.confirmButton.isUserInteractionEnabled = false

                           

            break
        





        , withCancel:  (err) in
        print("attempting to load information")
        )

    

现在,完美地设置了按钮颜色和标题。但是,按钮的操作仍然是 handleConfirm 而不是 handle Complete。

处理完整的样子

 @objc func handleComplete() 
           let workUser = self.workerUser
           let username = workUser?.name
           let post = notification?.poster
           let jobTitle = post?.category


           let alert = UIAlertController(title: "Completed? ",message:" Did you complete the job \(jobTitle!) for \(username!) ?", preferredStyle: UIAlertController.Style.alert)

           let cancelButton = UIAlertAction(title: "Not Yet!", style: .default, handler: (_ action: UIAlertAction) -> Void in
                  print("you pressed Yes, please button")
              )

           let continueButton = UIAlertAction(title: "Complete", style: .default, handler: (_ action: UIAlertAction) -> Void in
            self.fetchJobProgress()
            self.completeJobProgress()
            let hud = JGProgressHUD(style: .dark)
                  hud.textLabel.text = "Confirming!"
                    hud.show(in: self.view)


            hud.dismiss()
              )

           continueButton.setValue(GREEN_Theme, forKey: "titleTextColor")
           cancelButton.setValue(UIColor.red, forKey: "titleTextColor")
           alert.addAction(cancelButton)
           alert.addAction(continueButton)
           self.present(alert, animated: true, completion: nil)



func completeJobProgress() 
    let workUser = self.workerUser
    let uid = Auth.auth().currentUser?.uid
    let workerId = workUser?.uid
    let address = workerUser?.address
     let createDate = Int(NSDate().timeIntervalSince1970)

    Database.database().reference().child("users").child(uid!).observeSingleEvent(of: .value, with:  (snapshot) in
        guard let dictionary = snapshot.value as? [String : Any] else  return 
        let user = User(dictionary: dictionary as [String : AnyObject])
        workUser?.uid = snapshot.key

        let docData: [String: Any] = ["workerId": uid!,
                                      "creationDate": createDate,
                                      "fromId" : workerId!,
                                      "location": address!,
                                      "type": 3,
                                      "checked": 0,]

        self.setJobToCompletedInDatabase(uid: workerId!, values: docData as [String : AnyObject])
        self.updateUserDataIntoDatabseWithUID(uid: uid!, values: docData as [String : AnyObject])
        JOB_POST_REF.child(uid!).child("progress?").setValue(3)

     , withCancel:  (err) in
        print("attempting to load information")
        )

        print("Finished saving user info")
        self.dismiss(animated: true, completion: 
            print("Dismissal complete")
        )


    

    private func setJobToCompletedInDatabase(uid: String, values: [String: AnyObject]) 
        let hud = JGProgressHUD(style: .dark)
        hud.textLabel.text = "Saving"
        hud.show(in: view)

        let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
                    let usersReference = ref.child("completedJob").child(uid).childByAutoId()
                    usersReference.setValue(values, withCompletionBlock:  (err, ref) in
                    if err != nil 
                        print("error saving data into firebase")
                        return
                    

                    hud.dismiss()
                    self.dismiss(animated: true, completion: nil)
                )

    

两者的代码非常相同,而不是一些小的更改,但它应该保存在 firebase 的两个不同的树中。

既然按钮颜色和标题的背景都被成功改变了,我不明白为什么按钮的动作没有?

如果这太令人困惑,我可以添加图片。

【问题讨论】:

【参考方案1】:

您需要先删除该操作,然后再为按钮赋予新的操作:

关注代码:

self.confirmButton.removeTarget(nil, action: nil, for: .allEvents)

每当您设置新操作时添加此行。

更新方法:

func fetchJobProgress() 
            let workerId = workerUser?.uid
            let uid = Auth.auth().currentUser?.uid
        Database.database().reference().child("workInProgress").child(uid!).queryOrdered(byChild: "fromId").queryEqual(toValue: workerId).observeSingleEvent(of: .value, with:  (snapshot) in

                guard let dictionary = snapshot.value as? [String : Any] else  return 
            for (_, valueDic) in dictionary 
                guard let dic = valueDic as? [String: Any] else 
                    continue
                
                guard let type = dic["type"] as? Int else 
                    continue
                

                if type == userNotifications.NotificationType.inProgress.rawValue 
                    self.confirmButton.setTitle("Pending...", for: .normal)
                    self.confirmButton.backgroundColor = UIColor.lightGray
                    self.confirmButton.removeTarget(nil, action: nil, for: .allEvents)
                    self.confirmButton.addTarget(self, action: #selector(self.handleComplete), for: .touchUpInside)
                   // self.confirmButton.isUserInteractionEnabled = false

                 else if type == userNotifications.NotificationType.completed.rawValue 
                    self.confirmButton.setTitle("completed", for: .normal)
                    self.confirmButton.setTitleColor(.black, for: [])
                    self.confirmButton.backgroundColor = .white
                    self.confirmButton.isUserInteractionEnabled = false
                
                else 
                    self.confirmButton.backgroundColor = GREEN_Theme
                    self.confirmButton.removeTarget(nil, action: nil, for: .allEvents)
                    self.confirmButton.addTarget(self, action: #selector(self.handleConfirm), for: .touchUpInside)

                

                break
            





            , withCancel:  (err) in
            print("attempting to load information")
            )

        

【讨论】:

感谢您的帮助!!

以上是关于发出从 firebase 调用信息以设置按钮标题的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用firebase读取数据以反应本机

如何以安全的方式从 Cloud Tasks 调用 Firebase 函数?

如何从 Firebase 函数调用第三方 Rest API 以用于 Google 上的操作

从 firebase 检索数据并设置 VC 以匹配用户偏好

Firebase 网络通知没有错误但没有通知

写入 Firebase 时 Geofire 崩溃