【问题标题】:How to present an alert after view controller has been dismissed视图控制器关闭后如何显示警报
【发布时间】:2019-05-06 05:29:05
【问题描述】:

我有一个应用程序,用户在后台上传文件通常需要几秒钟。当他们点击“完成”按钮时开始上传,这也会关闭视图控制器。我希望发生的是在下载完成时出现警报。我以为我只需将下面的代码添加到上传功能,但它不起作用。如何让提示框出现以确认上传成功?

@IBAction func tapDone(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
    if let image = newImage {
        submit2Parse(image: image)
    }
}

func submit2Parse (image: UIImage) {
    if let pfImage = image2PFFile(image: image) {
        // Insert PFFile into parse server
        let submittedImage = PFObject(className: "Images")
        submittedImage["imageFile"] = pfImage
        submittedImage["type"] = "submittedFromUserHome"
        submittedImage["bride"] = brideSwitch.isOn
        submittedImage["groom"] = groomSwitch.isOn
        submittedImage["user"] = userSwitch.isOn
        submittedImage["picturePeriod"] = pickerSelected
        submittedImage["uploadedByUserId"] = PFUser.current()?.objectId ?? ""            submittedImage["uploadedByUserName"] = PFUser.current()?.username ?? ""
        if !txtIsPlaceHolder { submittedImage["description"] = imageDescription.text }

        submittedImage.saveInBackground { (success, error) in
            if success {
                let message = "Save in bg worked"
                print(message)
                let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: {
                    (action) in
                    self.dismiss(animated: true, completion: nil)
                }))
                self.present(alert,animated: true, completion: nil)

            } else {
                print(error?.localizedDescription ?? "")
            }
        }
    }
}

代码给了我这个构建错误:

在闭包中隐式使用“self”;使用“自我”。使捕获语义明确

【问题讨论】:

    标签: ios swift uialertcontroller


    【解决方案1】:

    在您的tapDone 方法中,您需要利用completion 解除您的控制器,如下所示:

    self.dismiss(animated: true) {
        if let image = newImage {
            self.submit2Parse(image: image)
        }
    }
    

    这仅意味着self.submit2Parse(image: image) 只会在您关闭控制器后执行。此外,错误

    在闭包中隐式使用“self”;使用“自我”。捕捉 语义显式

    仅表示您需要在闭包内使用self. 显式调用变量或方法。所以你的submit2Parse... 现在应该是这样的:

    self.submit2Parse(image: image).

    【讨论】:

      【解决方案2】:

      如果我正确理解了您的问题,您希望在用户点击 tapDone 按钮时关闭您的 SecondViewController。之后,一旦您的图片上传完成,您就会想要显示成功警报。

      但是,如果您dismiss,一旦点击按钮,您将不会收到任何警报,因为您的 SecondViewController 不再在 window hierarchy 中,如果您尝试显示警报,您将在控制台中收到错误消息,例如:

      尝试在 谁的观点不在 窗口层次结构!

      要解决此问题,您需要在您的第一个视图控制器中显示一个警报,该警报将在您关闭第二个视图控制器后出现,您可以通过 delegate 实现它。

      考虑下面的例子:

      首先在你的FirstViewController之外声明一个protocol

      protocol UplaodSuccessDelegate:class {
          func uploadSuccess(message: String)
      }
      

      然后确认你的代表到同一个班级:

      class ViewController: FirstViewController, UplaodSuccessDelegate {
      

      那么你在提交SecondViewController时需要传递委托:

      let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
      vc.delegate = self. //Pass delegate
      self.present(vc, animated: true, completion: nil)
      

      并将委托方法添加到同一个类:

      func uploadSuccess(message: String) {
      
          let message = "Save in bg worked"
          print(message)
          let alert = UIAlertController(title: "title", message: message, preferredStyle: UIAlertController.Style.alert)
          alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: {
              (action) in
      
          }))
          self.present(alert,animated: true, completion: nil)
      }
      

      现在你需要在SecondViewController 中添加

      weak var delegate: UplaodSuccessDelegate?
      

      并在您的 tapDone 方法中将代码替换为:

      self.dismiss(animated: true) {
          if let image = newImage {
              submit2Parse(image: image)
          }
      }
      

      上传完成后,您需要调用委托方法(上传完成后),例如:

      self.delegate?.uploadSuccess(message: "your message")
      

      这将从FirstViewController 调用您的委托方法。

      【讨论】:

      • 如果我不知道当前的视图控制器会是什么?我解雇了某些视图控制器,但用户很容易在上传时移动到另一个视图控制器。我知道我已经看到应用程序在下载发生后提醒用户,例如当 netflix 让您知道您的下载已完成时。有没有办法更改我的代码,以便在当前活动队列是什么时调用 alter?
      • 如果是这种情况,那么您可以从 AppDelegate 发出警报。检查这个:stackoverflow.com/questions/36155769/…
      【解决方案3】:

      当您将下面的函数放入在后台启动数据上传的 viewController 中,然后在提交完成时触发的闭包中调用此函数时,即使初始视图控制器是被解雇(如果上传时间很长,则被解雇)。

      // This is the function that performs my background upload
          func submit2Parse (image: UIImage) {
              if let pfImage = image2PFFile(image: image) {
                  // Insert PFFile into parse server
                  let submittedImage = PFObject(className: "Images")
                  submittedImage["imageFile"] = pfImage
                  submittedImage["imageCreateDt"] = newImageCreateDate
                  submittedImage["type"] = "submittedFromUserHome"
                  submittedImage["bride"] = brideSwitch.isOn
                  submittedImage["groom"] = groomSwitch.isOn
                  submittedImage["user"] = userSwitch.isOn
                  submittedImage["picturePeriod"] = pickerSelected
                  submittedImage["uploadedByUserId"] = PFUser.current()?.objectId ?? ""
                  submittedImage["uploadedByUserName"] = PFUser.current()?.username ?? ""
                  if !txtIsPlaceHolder { submittedImage["description"] = imageDescription.text }
                  // Get the image timestamp, every photo has one
                  // How do you get the thumbnail image too?
      
                  submittedImage.saveInBackground { (success, error) in
                      if success {
                          let message = "Save in bg worked"
                          print(message)
                          self.showAlertFromAppDelegates()
                      } else {
                          print(error?.localizedDescription ?? "")
                      }
                  }
              }
          }
      
      // This is the function that creates the alert
          func showAlertFromAppDelegates(){
              var topWindow: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
              topWindow?.rootViewController = UIViewController()
              topWindow?.windowLevel = UIWindow.Level.alert + 1
              let alert: UIAlertController =  UIAlertController(title: "Upload Complete", message: "Your image was successfully submitted!", preferredStyle: .alert)
              alert.addAction(UIAlertAction.init(title: "OK", style: .default, handler: { (alertAction) in
                  topWindow?.isHidden = true
                  topWindow = nil
              }))
              topWindow?.makeKeyAndVisible()
              topWindow?.rootViewController?.present(alert, animated: true, completion:nil)
          }
      

      【讨论】:

        猜你喜欢
        • 2020-10-02
        • 2018-06-01
        • 2020-12-05
        • 1970-01-01
        • 1970-01-01
        • 2016-03-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        相关资源
        最近更新 更多