视图控制器被解雇后如何显示警报

时间:2019-05-06 05:29:06

标签: ios swift uialertcontroller

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

@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 ?? "")
            }
        }
    }
}

代码给了我这个编译错误:

  

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

4 个答案:

答案 0 :(得分:1)

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

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

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

  

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

仅表示当您在闭包内部时,需要使用self.显式调用变量或方法。因此,您的submit2Parse...现在将如下所示:

self.submit2Parse(image: image)

答案 1 :(得分:0)

您已删除self.dismiss(animated: true, completion: nil) 来自

@IBAction func tapDone(_ sender: Any) {
    if let image = newImage {
        submit2Parse(image: image)
    }
}

或使用

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

因为viewController早于dismissed,而compiler却得不到viewController的{​​{1}}

答案 2 :(得分:0)

如果我正确理解了您的问题,那么您想在用户点击SecondViewController按钮时撤消tapDone。然后,一旦您的图片上传完成,您就希望对成功进行提醒。

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

  

尝试出席    他的观点不在   窗口层次结构!

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

考虑以下示例:

首先在您的protocol之外声明FirstViewController

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调用您的委托方法。

答案 3 :(得分:0)

当您将下面的函数放到viewController中以在后台启动数据上传,然后在提交完成时触发的闭包中调用此函数时,即使最初的view controller是被解雇(或如果长时间上传则被解雇)。

// 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)
    }