前置き
やりたいこと
アプリ内からメールを送れるようにしたい。
sheetを用いてメーラーを表示し、ユーザーはそこで編集・送信・キャンセル等を行う。
環境
- Xcode: 11.2.1
- Swift: 5.1.2
- 実機: 13.2.3
実装
下記のMailViewというViewを用意して、必要な箇所(今回の場合はContentView)でそれを呼び出すようにします。
MailView.swift
import SwiftUI
import MessageUI
struct MailView: UIViewControllerRepresentable {
@Binding var isShowing: Bool
func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> UIViewController {
let controller = MFMailComposeViewController()
controller.mailComposeDelegate = context.coordinator
controller.setSubject("これが件名")
controller.setToRecipients(["hogehoge@hogehoge.com"])
controller.setMessageBody("これが本文", isHTML: false)
return controller
}
func makeCoordinator() -> MailView.Coordinator {
return Coordinator(parent: self)
}
class Coordinator: NSObject, MFMailComposeViewControllerDelegate, UINavigationControllerDelegate {
let parent: MailView
init(parent: MailView) {
self.parent = parent
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
// 終了時の処理あれこれ
self.parent.isShowing = false
}
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<MailView>) {
}
}
呼び出し側
ContentView.swift
import SwiftUI
import MessageUI
struct ContentView: View {
@State private var isShowingMailView = false
var body: some View {
Button(action: {
self.isShowingMailView.toggle()
}) {
Text("Open MailView")
}
.disabled(!MFMailComposeViewController.canSendMail())
.sheet(isPresented: $isShowingMailView, content: {
MailView(isShowing: self.$isShowingMailView)
})
}
}
動作gif
ボタンを押してMailViewを開き、その後はキャンセルボタンを押して下の画面に戻っています。
※ 差出人メールアドレスは一時的に変更した仮のものを使用しています。