1

I created a custom class named PreviewFile:

class PreviewFile: UIViewController , UIDocumentInteractionControllerDelegate {

     var documentInteractionController = UIDocumentInteractionController()


    func previewFile(name:String)  {

        let documentsURL = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!,isDirectory: true )
        let urlToMyPath = documentsURL.appendingPathComponent(name)!

        documentInteractionController = UIDocumentInteractionController(url: urlToMyPath)
        documentInteractionController.delegate = self
        documentInteractionController.presentPreview(animated: true)

    }



    public  func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {

        return self

    }

}

Then I call the previewFile method on a ViewController :

var preview = PreviewFile()
preview.previewFile(name:"guide.pdf")

But compiler gives me this error :

Warning: Attempt to present on whose view is not in the window hierarchy!

1
  • What you are doing here from this line var preview = PreviewFile() this line only take copy of the class but not the View attached to that class. try let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil) let controller = storyboard.instantiateViewController(withIdentifier: "someViewController") as! yourViewControllerClass and call like this controller.previewFile(name:"guide.pdf") Commented May 23, 2017 at 12:05

1 Answer 1

1
class PreviewFile: UIViewController , UIDocumentInteractionControllerDelegate {

    private var controller: UIViewController!

    func previewFile(name:String, in controller: UIViewController)  {
        self.controller = controller
        let documentsURL = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!,isDirectory: true )
        let urlToMyPath = documentsURL.appendingPathComponent(name)!

        let documentInteractionController = UIDocumentInteractionController(url: urlToMyPath)
        documentInteractionController.delegate = self
        documentInteractionController.presentPreview(animated: true)

    }



    public func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {

        return self.controller

    }

}

then you will be able to call it from UIViewController like that:

var preview = PreviewFile()
preview.previewFile(name:"guide.pdf", in self)

You have this issue because you are trying to show documentDirectory from PreviewFile controller, what is not presented on screen

UPDATE #1 Better solution

class PreviewFile: NSObject, UIDocumentInteractionControllerDelegate {
private var controller: UIViewController!

init(controller: UIViewController) {
    super.init()
    self.controller = controller
}

func previewFile(name:String)  {
    let documentsURL = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!,isDirectory: true )
    let urlToMyPath = documentsURL.appendingPathComponent(name)!

    let documentInteractionController = UIDocumentInteractionController(url: urlToMyPath)
    documentInteractionController.delegate = self
    documentInteractionController.presentPreview(animated: true)
}


public func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {

    return self.controller

}
}

call it like that:

var preview = PreviewFile(controller: self)
preview.previewFile(name:"guide.pdf")
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks ! I did not noticed that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.