Click alert button to show MFMailComposeViewContro

2019-08-22 12:42发布

Trying to use MFMailComposeViewController when click alert button. But when I click alert button, controller doesn't pop-up. The code is below. I used extension and I'm trying to call sendmail function when clicking alert button.

extension Alert:MFMailComposeViewControllerDelegate {
    func sendmail(){
        let mailComposeViewController = configureMailController()
        if MFMailComposeViewController.canSendMail() {
            let VC = storyboard?.instantiateViewController(withIdentifier: "MainVC")
            VC?.present(mailComposeViewController, animated: true, completion: nil)
        } else {
            showMailError()
        }
    }

    func configureMailController() -> MFMailComposeViewController {
        let mailComposerVC = MFMailComposeViewController()
        let VC = storyboard?.instantiateViewController(withIdentifier: "MainVC")
        mailComposerVC.mailComposeDelegate = VC as? MFMailComposeViewControllerDelegate

        mailComposerVC.setToRecipients(["**"])
        mailComposerVC.setSubject("**")
        mailComposerVC.setMessageBody("\n\n\n\nModel: \nSistem versiyon: )\nuygulamaversiyon:", isHTML: false)

        return mailComposerVC
    }

    func showMailError() {
        let sendMailErrorAlert = UIAlertController(title: "Could not send email", message: "Your device could not send email", preferredStyle: .alert)
        let dismiss = UIAlertAction(title: "Ok", style: .default, handler: nil)
        sendMailErrorAlert.addAction(dismiss)
        let VC = storyboard?.instantiateViewController(withIdentifier: "MainVC")
        VC?.present(sendMailErrorAlert, animated: true, completion: nil)
    }

    public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true, completion: nil)
    }
}

1条回答
\"骚年 ilove
2楼-- · 2019-08-22 13:33

Your code tries to present the mail view controller (and also the error alert) on a new view controller which you create with instantiateViewController. Since this new VC itself is not part of your app's VC hierarchy, neither it nor the mail VC will appear on screen.

To make this work, you can either pass a view controller which is part of your app into your sendmail method:

func sendmail(_ root: UIViewController) {
  ...
  root.present(mailComposeViewController, animated: true, completion: nil)
  ...

Or you can use a globally accessible VC of your app; in a simple app using the root VC should work:

func sendmail() {
  ...
  let root = UIApplication.shared.keyWindow?.rootViewController
  root?.present(mailComposeViewController, animated: true, completion: nil)
  ...

I'd suggest the first approach because it is more flexible (e.g. it allows you to open your mail screen anywhere, even when your VC hierarchy gets more complex).

查看更多
登录 后发表回答