MFMailComposeViewController does not dismiss
Asked Answered
N

7

17

I'm trying to implement MFMailComposeViewController in case of sending the emails from within my application. The problem is that after presenting MFMailComposeViewController it is not dismissing by "Cancel" or "Send" buttons, just a bit scrolls up.

Here is the presenting of it:

func mailButtonDidPressed {
        let emailTitle = "Test email"
        let messageBody = "some body bla bla bla"
        let toRecipents = "[email protected]"

        let emailComposer = MFMailComposeViewController()
        emailComposer.setSubject(emailTitle)
        emailComposer.setMessageBody(messageBody, isHTML: false)
        emailComposer.setToRecipients([toRecipents])
        emailComposer.mailComposeDelegate = self
        self.presentViewController(emailComposer, animated: true, completion: nil)
    }

and dismissing delegate code:

func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
    switch (result) {
    case MFMailComposeResultSent:
        print("You sent the email.")
        break
    case MFMailComposeResultSaved:
        print("You saved a draft of this email")
        break
    case MFMailComposeResultCancelled:
        print("You cancelled sending this email.")
        break
    case MFMailComposeResultFailed:
        print("Mail failed:  An error occurred when trying to compose this email")
        break
    default:
        print("An error occurred when trying to compose this email")
        break
    }

    controller.dismissViewControllerAnimated(true, completion: nil)
}

I have surfed through the StackOverflow and other services like this and could not find any answer.

Neddy answered 9/8, 2016 at 13:16 Comment(5)
does didFinishWithResult is called..? i mean have you added delegate?Carolecarolee
I tested your code. It's working just fine.Kilauea
kind of a miracle, because it still doesn't workNeddy
Try testing it on an actual device if you haven't.Kilauea
I do test it on my iPhone, not on SimulatorNeddy
P
13

Swift 5

Remember to add both delegates:

emailComposer.mailComposeDelegate = self
emailComposer.delegate = self

If you only add one, it won't dismiss. Also make sure to implement the delegate method:

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    dismiss(animated: true)
}
Peruke answered 20/7, 2019 at 7:24 Comment(1)
Works for me like a charm! Thanks Ken.Melodee
P
9

If anybody's having this problem in Swift 3.0, I think there might be two methods for MFMailComposeViewController that look similar to the CORRECT method.

Make sure you are using this method

  func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        controller.dismiss(animated: true, completion: nil)
    }
Poulson answered 22/3, 2017 at 16:32 Comment(2)
@HusseinAlBehary yay!Poulson
This worked for me too! For some reason apple's example here developer.apple.com/documentation/messageui/… wasn'tBigford
S
6

for swift 3 you have to add

        composer.mailComposeDelegate = self as MFMailComposeViewControllerDelegate
Selfdetermination answered 29/4, 2017 at 1:11 Comment(0)
G
5

I solved writing in this way removing the completion in this way:

extension UIViewController: MFMailComposeViewControllerDelegate {

    func sendEmail() {
      //send email
    }

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

}
Godolphin answered 29/5, 2017 at 13:44 Comment(0)
W
0

Assuming mailComposeControllermailComposeControlleris a function of the same class as mailButtonDidPressedmailButtonDidPressed, it should be its instance that dismiss the MFMailComposeViewController, so

self.dismissViewControllerAnimated(true, completion: nil)

instead of

controller.dismissViewControllerAnimated(true, completion: nil)

Wieldy answered 9/8, 2016 at 13:20 Comment(1)
I've got exactly the same resultNeddy
F
0

You didn't add the delegate :

emailComposer.delegate = self 

your code should be like this :

func mailButtonDidPressed {
        ...

        let emailComposer = MFMailComposeViewController()
       emailComposer.delegate = self 

...
    }
Falla answered 9/8, 2016 at 13:24 Comment(8)
emailComposer.mailComposeDelegate = self I can see this in OPs code.Misunderstanding
I'm not sure 100% but it's not the sameFalla
emailComposer.delegate = self this delegate should conform UINavigationControllerDelegate, are sure that I should conform to that protocol in my view controller?Neddy
Please can you add debug point at controller.dismissViewControllerAnimated(true, completion: nil) and show me what you got in debugger ?Falla
2016-08-09 16:32:01.806 MyProject[2899:1110844] Presenting view controllers on detached view controllers is discouraged < MyProject.ViewController: 0x13096a470>. You cancelled sending this email.Neddy
are you using swift 2 or 3 ?Falla
@user3224534 It looks like you are presenting view controller from the child view controller. can you try presenting from parent ?Misunderstanding
double checked what I've done, after GoodSp33d hint, there was a problem with my navigation flow, thank you, problem solvedNeddy
S
0

I had this problem and the answer was extremely simple. Make sure to include

MFMailComposeViewControllerDelegate

in the top as when you are listing your inheritances, and then include the stuff from the other answers.

Swink answered 17/2, 2018 at 0:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.