SwiftUI: Send email

前端 未结 6 1505
小蘑菇
小蘑菇 2020-12-08 02:06

In a normal UIViewController in Swift, I use this code to send a mail.

let mailComposeViewController = configuredMailComposeViewController()

ma         


        
6条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-08 02:48

    As you mentioned, you need to port the component to SwiftUI via UIViewControllerRepresentable.

    Here's a simple implementation:

    struct MailView: UIViewControllerRepresentable {
    
        @Binding var isShowing: Bool
        @Binding var result: Result?
    
        class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
    
            @Binding var isShowing: Bool
            @Binding var result: Result?
    
            init(isShowing: Binding,
                 result: Binding?>) {
                _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) -> MFMailComposeViewController {
            let vc = MFMailComposeViewController()
            vc.mailComposeDelegate = context.coordinator
            return vc
        }
    
        func updateUIViewController(_ uiViewController: MFMailComposeViewController,
                                    context: UIViewControllerRepresentableContext) {
    
        }
    }
    

    Usage:

    struct ContentView: View {
    
        @State var result: Result? = 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)
            }
    
        }
    
    }
    

    (Tested on iPhone 7 Plus running iOS 13 - works like a charm)

    Updated for Xcode 11.4

提交回复
热议问题