首页 > 解决方案 > I want email address from 2nd ViewController to be used for mail.setToRecipients([myTextField.text ?? ""])

问题描述

I have 2 ViewControllers, the second one has a textField which the user can set their default email address in, so they do not have to input it every time the app is to send off an email.

The button to send email is on the first ViewController. After entering comments, details etc, they hit the "send" email button and the standard mail composer pops up.

Now here is where the To recipients should be automatically set to their default email address which is from the text field back on the second ViewController.

The ViewControllers are setup with basic segues (show) I don't know how to pass data between ViewControllers, I only recently started to code, so i am very new at this.

I have the below code so far

ViewController1

//  Created by Mark Smith on 14/7/19.
//  Copyright © 2019 Mark Smith. All rights reserved.
//

import UIKit
import MessageUI



class ViewController: UIViewController, MFMailComposeViewControllerDelegate
{

    //// Outlets //////////////////////////////////////////////////////////
    @IBOutlet weak var DateTextField: UITextField!
    @IBOutlet weak var ScrollView: UIScrollView!
    @IBOutlet weak var FirstTextView: UITextField!
    @IBOutlet weak var FirstName: UITextField!
    @IBOutlet weak var LastName: UITextField!
    @IBOutlet weak var Street: UITextField!
    @IBOutlet weak var Area: UITextField!
    @IBOutlet weak var PostCode: UITextField!
    @IBOutlet weak var Phone: UITextField!
    @IBOutlet weak var Email: UITextField!
    @IBOutlet weak var Reference: UITextView!
    @IBOutlet weak var OtherDetailsField: UITextView!
    @IBOutlet weak var SendEmail: UIBarButtonItem!
    @IBOutlet weak var ReferenceTextField: UITextView!


    /////-------------------------------------------------

    /////-----------------------

    lazy var datePicker: UIDatePicker = {
        let picker = UIDatePicker()
        picker.datePickerMode = .date
        picker.addTarget(self, action: #selector(datePickerChanged(_:)), for: .valueChanged)
        return picker
    }()
    lazy var dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .long
        formatter.timeStyle = .none
        return formatter
    }()


    // Send Email -----------------------------------
    @IBAction func SendEmail(_ sender: UIBarButtonItem) {
        //MARK: IBAction Method for Button click
            //TODO:  You should check if we can send email or not
            if MFMailComposeViewController.canSendMail() {
                let mail = MFMailComposeViewController()
                mail.mailComposeDelegate = self
                mail.setToRecipients([Email.text ?? ""])
                mail.setSubject("Customer Called Today")
                mail.setMessageBody("Date: \(String(describing: DateTextField.text ?? "nil"))</br>\nFirst Name: \(String(describing: FirstName.text ?? "nil"))</br>\nLast Name: \(String(describing: LastName.text ?? "nil"))</br>\nStreet: \(String(describing: Street.text ?? "nil"))</br>\nArea: \(String(describing: Area.text ?? "nil"))</br>\nPost Code: \(String(describing: PostCode.text ?? "nil"))</br>\nPhone: \(String(describing: Phone.text ?? "nil"))</br>\nEmail:  \(String(describing: Email.text ?? "nil"))</br>\nReference: \(String(describing: Reference.text ?? "nil"))</br>\nOther Details: \(String(describing: OtherDetailsField.text ?? "nil")) ", isHTML: true)
              //  mail.setMessageBody = DateTextField.text
                //Body = textBox3.Text;
                present(mail, animated: true)
            } else {
                print("Application is not able to send an email")
            }
        }

        //MARK: MFMail Compose ViewController Delegate method
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {

        // Dismiss the mail compose view controller.
        controller.dismiss(animated: true, completion: nil)
    }



    // Adjust Scroll for Keyboard ------------------
    @objc func adjustForKeyboard(notification: Notification) {
        guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
        let keyboardScreenEndFrame = keyboardValue.cgRectValue
        let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)
        if notification.name == UIResponder.keyboardWillHideNotification {
            ScrollView.contentInset = .zero
        } else {
            ScrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
        }
        ScrollView.scrollIndicatorInsets = ScrollView.contentInset
      //  let selectedRange = OtherDetailsField.selectedRange
      //  OtherDetailsField.scrollRangeToVisible(selectedRange)
    }



    //// View Did Load  ///////////////////////////////////////

    override func viewDidLoad(){
        super.viewDidLoad()
        // Do any additional setup after loading the view.


        //Set date as today's date
        let todaysDate = Date()
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "dd MMMM yyyy"
        let dateString = dateFormatter.string(from: todaysDate)
        DateTextField.text = dateString

        // Adjust Scroll for Keyboard ---------------
        let notificationCenter = NotificationCenter.default
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)


        // Date Picker ---------------
        DateTextField.inputView = datePicker}
    @objc func datePickerChanged(_ sender: UIDatePicker){
        DateTextField.text = dateFormatter.string(from: sender.date)
    }
   //     `$`(".date-pick").datepicker();
     //   `$`(".date-pick").datepicker("setDate",new, Date());

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){view.endEditing(true)
    }

    // Dismiss Keyboard ------------------
    func setupKeyboardDismissRecognizer(){
        let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(
            target: self, action: #selector(ViewController.dismissKeyboard))
        tapRecognizer.cancelsTouchesInView = false
        self.view.addGestureRecognizer(tapRecognizer)
    }
    @objc func dismissKeyboard()
    {
        view.endEditing(true)
    }


    ///////
}
// Add Done Button to keypad toolbar -----------------
extension UITextField{

    @IBInspectable var doneAccessory: Bool{
        get{
            return self.doneAccessory
        }
        set (hasDone) {
            if hasDone{
                addDoneButtonOnKeyboard()
            }
        }
    }

    func addDoneButtonOnKeyboard()
    {
        let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        doneToolbar.barStyle = .default

        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))

        let items = [flexSpace, done]
        doneToolbar.items = items
        doneToolbar.sizeToFit()

        self.inputAccessoryView = doneToolbar
    }

    @objc func doneButtonAction()
    {
        self.resignFirstResponder()
    }
}
extension UITextView{

    @IBInspectable var doneAccessory: Bool{
        get{
            return self.doneAccessory
        }
        set (hasDone) {
            if hasDone{
                addDoneButtonOnKeyboard()
            }
        }
    }

    func addDoneButtonOnKeyboard()
    {
        let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        doneToolbar.barStyle = .default

        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))

        let items = [flexSpace, done]
        doneToolbar.items = items
        doneToolbar.sizeToFit()

        self.inputAccessoryView = doneToolbar
    }

    @objc func doneButtonAction()
    {
        self.resignFirstResponder()
    }
}

ViewController2

//  Created by Mark Smith on 18/7/19.
//  Copyright © 2019 Mark Smith. All rights reserved.
//

import UIKit

class ViewController2: UIViewController {

    //// Outlets //////////////////////////////////////////////////////////

    @IBOutlet weak var ScrollView: UIScrollView!
    @IBOutlet weak var DefaultSubject: UITextField!
    @IBOutlet weak var DefaultEmail: UITextField!




    // Adjust Scroll for Keyboard ------------------
    @objc func adjustForKeyboard(notification: Notification) {
        guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
        let keyboardScreenEndFrame = keyboardValue.cgRectValue
        let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)

        if notification.name == UIResponder.keyboardWillHideNotification {
            ScrollView.contentInset = .zero
        } else {
            ScrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
        }
        ScrollView.scrollIndicatorInsets = ScrollView.contentInset
        //let selectedRange = yourTextView.selectedRange
        //yourTextView.scrollRangeToVisible(selectedRange)
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.


        // Adjust Scroll for Keyboard ---------------
        let notificationCenter = NotificationCenter.default
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */
        // Dismiss Keyboard ------------------
        func setupKeyboardDismissRecognizer(){
            let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(
                target: self, action: #selector(ViewController.dismissKeyboard))
            tapRecognizer.cancelsTouchesInView = false
            self.view.addGestureRecognizer(tapRecognizer)
        }
        func dismissKeyboard()
        {
            view.endEditing(true)
        }
    }

标签: iosswift

解决方案


You can achieve this by using Delegation Pattern,

Step 1

protocol EmailSubmissionDelegate {
func emailSubmitted(email:String)
}

class ViewController2: UIViewController {

var emailSubmissionDelegate:EmailSubmissionDelegate?
//rest of the code...
}

and wherever user set the default email in ViewController2, call,

emailSubmissionDelegate?.emailSubmitted(email: "<#T##String#>")

Step 2

Implement the protocol in ViewController

class ViewController: UIViewController, MFMailComposeViewControllerDelegate, EmailSubmissionDelegate  {

func emailSubmitted(email: String) {
/* Add the email to the textfield 
E.g:
emailTextField.text = email
*/
}

}

Step 3

Make sure you initialize the delegate in prepare for segue method in ViewController

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
       let viewController2 = segue.destination as! ViewController2
        viewController2.emailSubmissionDelegate = self
    }

推荐阅读