Как вы упомянули, вам нужно перенести компонент на 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>?
@State var isShowingMailView = false
var body: some View {
ZStack {
VStack {
Button(action: {
self.isShowingMailView.toggle()
}) {
Text("Show mail view")
}
if result != nil {
Text("Result: \(String(describing: result))")
.lineLimit(nil)
}
}
if (isShowingMailView) {
mailView()
.transition(.move(edge: .bottom))
.animation(.basic())
}
}
}
private func mailView() -> some View {
MFMailComposeViewController.canSendMail() ?
AnyView(MailView(isShowing: $isShowingMailView, result: $result)) :
AnyView(Text("Can't send emails from this device"))
}
}
Примечания :
Я использую ZStack
, чтобы показать это, так как поведение Modal
было весьма противоречивым.
(протестировано на iPhone 7 Plus под управлением iOS 13 - работает как шарм)