Search code examples
iosswiftstackuidocumentpickervc

Where to use popToRootViewController to pop extra VC off stack?


I have a view controller with two buttons: Button1 brings up the documentPickerViewController and lets user pick a file. Button2 goes to a second view controller.

Button1 is linked to "openFile" in the code below. Button2 calls the segue to the second view controller.

So this is how I get the problem: Click Button1, document picker shows up. If I pick a document, then document picker disappears and I'm back to view controller. So far so good.

Now I press Button2. Second view controller shows up. All good. I exit and go back to 1st view controller.

Now I press Button1 again. Document picker shows up. But this time I click "cancel". Document picker disappears but the SECOND view controller appears!

I get "Unbalanced calls to begin/end appearance transitions for <_UIWaitingForRemoteViewContainerViewController: 0x122206480>." and "[DocumentManager] The view service did terminate with error: Error Domain=_UIViewServiceErrorDomain Code=1 "(null)" UserInfo={Terminated=disconnect method}"

From researching I understand that I must have popped an extra 2nd view controller to the stack but I can't see where I would have done it and also where would be the appropriate place to pop it?

I've tried setting "animated: false" and that didn't make any difference.

Thanks in advance.

@IBAction func openFile(_ sender: Any) {

    let documentPicker: UIDocumentPickerViewController = UIDocumentPickerViewController(documentTypes: ["public.text"], in: UIDocumentPickerMode.import)
    documentPicker.delegate = self
    documentPicker.modalPresentationStyle = UIModalPresentationStyle.fullScreen
    self.present(documentPicker, animated: true, completion: nil)

}


func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {

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

}

func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
    if controller.documentPickerMode == UIDocumentPickerMode.import {
        var textRead = ""
        do {
            if urls.count > 0 {
                for i in 0...urls.count-1 {
                    textRead = try String(contentsOf: urls[i], encoding: .utf8)
                    textView.text = textView.text + textRead
                }
            }
        }
        catch {
            /* error handling here */
            print("There's a problem reading the file")
        }

    }

}

Solution

  • After more experimenting and researching, I found this stopped the 2nd view controller from appearing, even though the two error messages are still appearing:

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
    
        //self.dismiss(animated: true, completion: nil)
        self.navigationController?.popToRootViewController(animated: true)
    }
    

    Would still appreciate if someone can suggest a more elegant solution which eliminates the error messages altogether.

    EDIT:

    After playing with it a bit more, I found the fix!

    We only need this:

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
    
        // do nothing. The picker is dismissed anyway.
    }
    

    So the dismiss statement was causing the problem. By leaving out any dismiss picker call, the picker window closes anyway.