简体   繁体   English

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

[英]How to present an alert after view controller has been dismissed

I have an app where a user uploads a file in the background that usually takes a couple of seconds. 我有一个应用程序,用户在后台上传文件通常需要几秒钟。 The upload is kicked off when they tap a "Done" button and that also dismisses the view controller. 当他们点击“完成”按钮时,上传开始,这也将关闭视图控制器。 What I would I would like to happen is an alert comes up when the download is done. 我希望发生的是下载完成时出现警报。 I thought I would just add the code below to the upload function but it isn't working. 我以为我只是将下面的代码添加到上载功能中,但它不起作用。 How can I have an alert box appear to confirm that that the upload was successful? 如何显示一个警报框,以确认上传成功?

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

The code gives me this build error: 代码给了我这个构建错误:

Implicit use of 'self' in closure; 封闭中隐式使用“自我”; use 'self.' 使用“自我”。 to make capture semantics explicit 使捕获语义明确

In your tapDone method, you need to utilize the completion of the dismissal of your controller, like so: tapDone方法中,您需要利用控制器tapDonecompletion ,如下所示:

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

This only means that the self.submit2Parse(image: image) will ONLY be executed after you dismiss the controller. 这仅意味着self.submit2Parse(image: image)仅在关闭控制器后执行。 Additionally, the error 此外,错误

Implicit use of 'self' in closure; 封闭中隐式使用“自我”; use 'self.' 使用“自我”。 to make capture semantics explicit 使捕获语义明确

only means that you need to use self. 仅表示您需要使用self. to explicitly call a variable or method when you're inside a closure. 在闭包内部时显式调用变量或方法。 So your submit2Parse... would now be like this: 因此,您的submit2Parse...现在将如下所示:

self.submit2Parse(image: image) . self.submit2Parse(image: image)

If I understood your question correctly you want to dismiss your SecondViewController when user tap on tapDone button. 如果我理解正确你的问题,你要解雇你SecondViewController当用户水龙头tapDone按钮。 And after that once your image upload complete then you want to present alert for success. 之后,一旦您的图片上传完成,您就希望对成功进行提醒。

But if you dismiss it once button tapped you won't get any alert because your SecondViewController is no longer in window hierarchy and if you will try to present the alert you will get an error in Console like: 但是,如果您在单击按钮后将其dismiss则您将不会收到任何警报,因为您的SecondViewController不再处于window hierarchy并且如果尝试显示警报,则会在Console中收到错误消息,例如:

Attempt to present on whose view is not in the window hierarchy! 尝试呈现不在窗口层次结构中的视图!

To solve this problem you need to present a alert from your first view controller which will appear after you dismiss your second view controller and you can achieve it with delegate . 要解决此问题,您需要从您的第一个视图控制器发出警报,该警报将在您关闭第二个视图控制器后出现,并且可以使用delegate实现它。

Consider the below example: 考虑以下示例:

First of all declare a protocol outside your FirstViewController : 首先在FirstViewController外部声明一个protocol

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

then confirm your delegate to same class: 然后确认您的代表参加同一个班级:

class ViewController: FirstViewController, UplaodSuccessDelegate {

then you need to pass the delegate when you present SecondViewController : 那么当您显示SecondViewController时,您需要传递委托:

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

and add delegate method to same class: 并将委托方法添加到同一类:

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

now in your SecondViewController you need to add 现在在您的SecondViewController您需要添加

weak var delegate: UplaodSuccessDelegate?

and in your tapDone method replace a code with: 在您的tapDone方法中,将代码替换为:

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

and once your upload complete you need to call delegate method (once your upload completes) like: 上传完成后,您需要调用委托方法(一旦上传完成),如下所示:

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

This will call your delegate method from FirstViewController . 这将从FirstViewController调用您的委托方法。

When you drop the function below into the viewController that initiates the data upload in the background, and then call this function in the closure that fires when the submit completes it is able to successfully create an alert even thought the initial view controller was dismissed (or long dismissed if it was a long upload). 当您将下面的函数放到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)
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 模态视图控制器被关闭后如何调用函数 - How to call a function when a Modal View Controller has been dismissed 如何检查视图 controller 是否已在 Swift 中被取消 - How to check if a view controller has been dismissed in Swift 尝试关闭UIViewController后再次显示它 - Attempt to again present UIViewController after it has been dismissed 如何以模态方式呈现ViewController,然后在ViewController被解除后运行一个回调函数/块,没有Delegate? - How to modally present a ViewController, and then the run a callback function / block after the ViewController has been dismissed, without Delegate? iOS视图控制器内存在被解除后未释放 - iOS view controller memory not released after it's been dismissed 关闭视图后显示警报 Controller - Present alert after dismissing View Controller ECSlidingViewController中的Top View Controller是否有办法知道边栏菜单何时被关闭? - Is there a way for the Top View Controller in ECSlidingViewController to know when the sidebar menu has been dismissed? 在iOS上关闭View Controller后,如何继续播放音频? - How to continue to play audio after view controller is dismissed on iOS? 在发送方视图控制器被解除后执行 segue - Performing segue after sender view controller is dismissed 关闭UIPopoverController后呈现视图控制器 - Presenting a View Controller after a UIPopoverController is dismissed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM