SwiftUI:发送电子邮件

标签 swift mfmailcomposeviewcontroller swiftui messageui

在正常 UIViewController在 Swift 中,我使用此代码发送邮件。

let mailComposeViewController = configuredMailComposeViewController()

mailComposeViewController.navigationItem.leftBarButtonItem?.style = .plain
mailComposeViewController.navigationItem.rightBarButtonItem?.style = .plain
mailComposeViewController.navigationBar.tintColor = UIColor.white

if MFMailComposeViewController.canSendMail() {
    self.present(mailComposeViewController, animated: true, completion: nil)
} else {
    self.showSendMailErrorAlert()
}

如何在 SwiftUI 中实现相同的目标?

我是否需要使用 UIViewControllerRepresentable ?

最佳答案

正如您所提到的,您需要将组件移植到 SwiftUI通过 UIViewControllerRepresentable .

这是一个简单的实现:

struct MailView: UIViewControllerRepresentable {

    @Binding var isShowing: Bool
    @Binding var result: Result<MFMailComposeResult, Error>?

    class Coordinator: NSObject, MFMailComposeViewControllerDelegate {

        @Binding var isShowing: Bool
        @Binding var result: Result<MFMailComposeResult, Error>?

        init(isShowing: Binding<Bool>,
             result: Binding<Result<MFMailComposeResult, Error>?>) {
            _isShowing = isShowing
            _result = result
        }

        func mailComposeController(_ controller: MFMailComposeViewController,
                                   didFinishWith result: MFMailComposeResult,
                                   error: Error?) {
            defer {
                isShowing = false
            }
            guard error == nil else {
                self.result = .failure(error!)
                return
            }
            self.result = .success(result)
        }
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(isShowing: $isShowing,
                           result: $result)
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<MailView>) -> MFMailComposeViewController {
        let vc = MFMailComposeViewController()
        vc.mailComposeDelegate = context.coordinator
        return vc
    }

    func updateUIViewController(_ uiViewController: MFMailComposeViewController,
                                context: UIViewControllerRepresentableContext<MailView>) {

    }
}

用法 :

struct ContentView: View {

    @State var result: Result<MFMailComposeResult, Error>? = nil
    @State var isShowingMailView = false

    var body: some View {

        VStack {
            if MFMailComposeViewController.canSendMail() {
                Button("Show mail view") {
                    self.isShowingMailView.toggle()
                }
            } else {
                Text("Can't send emails from this device")
            }
            if result != nil {
                Text("Result: \(String(describing: result))")
                    .lineLimit(nil)
            }
        }
        .sheet(isPresented: $isShowingMailView) {
            MailView(isShowing: self.$isShowingMailView, result: self.$result)
        }

    }

}

(在运行 iOS 13 的 iPhone 7 Plus 上测试 - 效果很好)

为 Xcode 11.4 更新

关于SwiftUI:发送电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56784722/

相关文章:

ios - 带有 iCloud 的 CoreData 驱动应用程序中带有 NSSortDescriptor 和 NSFetchedResultsController 的自定义部分

json - 如何在 swift 4 中使用 Graphql 获取 json 值数组?

ios - 在边的变换中检索 x

ios - 如何判断文件是否已发送或是否在 iOS 邮件的发件箱中

ios - 调整 MFMailComposeViewController 的大小并防止它覆盖整个屏幕

ios - 快速组合 : no `distinct` operator?

swift - 当 SwiftUI Picker 选择更改时,有没有办法调用函数?

swift - 这个 `[unowned self] in` Swift 代码在做什么?

ios - 将 MFMailComposeViewController 与 UIActionSheet 一起使用时崩溃

具有自定义类型的 SwiftUI 可绑定(bind)属性将无法编译