I have a little trouble with the ContactsUI in my app. With iOS 16 when I want add a contact there are not the cancel and done button. Have someone an idea how to solve it ? I have attached code and screen
import SwiftUI
import Foundation
import ContactsUI
struct EditInternalContactView: UIViewControllerRepresentable {
typealias UIViewControllerType = CNContactViewController
var contact: Binding<CNContact>
var presentingEditContact: Binding<Bool>
func makeCoordinator() -> EditInternalContactView.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<EditInternalContactView>) -> Self.UIViewControllerType {
let controller = CNContactViewController(forNewContact: contact.wrappedValue)
controller.delegate = context.coordinator
return controller
}
func updateUIViewController(
_ uiViewController: EditInternalContactView.UIViewControllerType,
context: UIViewControllerRepresentableContext<EditInternalContactView>) {}
}
extension EditInternalContactView {
final class Coordinator: NSObject, CNContactViewControllerDelegate {
var parent: EditInternalContactView
init(_ contactDetail: EditInternalContactView) {
self.parent = contactDetail
}
func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
parent.contact.wrappedValue = contact ?? parent.contact.wrappedValue
parent.presentingEditContact.wrappedValue = false
}
func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
return true
}
}
}
I solved the issue, so I post the answer for all the one who has the same problem.
The problem was that the controller must be into a UINavigationController and you expose the navigation Controller.
Here the code:
import Foundation
import ContactsUI
import SwiftUI
struct ContactView: UIViewControllerRepresentable {
var isPresenting: Binding<Bool>
var contact: CNContact?
func makeCoordinator() -> ContactView.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ContactView>) -> UIViewController {
let contactViewController = makeContactViewController
let navigationController = UINavigationController(rootViewController: contactViewController)
contactViewController.delegate = context.coordinator
return navigationController
}
func updateUIViewController(
_ uiViewController: UIViewController,
context: UIViewControllerRepresentableContext<ContactView>) {}
private var makeContactViewController: CNContactViewController {
if let contact = self.contact {
let viewController = CNContactViewController(forNewContact: contact)
viewController.title = nil
return viewController
} else {
return CNContactViewController(forNewContact: contact)
}
}
}
extension ContactView {
final class Coordinator: NSObject, CNContactViewControllerDelegate {
var parent: ContactView
init(_ contactView: ContactView) {
self.parent = contactView
}
func contactViewController(
_ viewController: CNContactViewController,
didCompleteWith contact: CNContact?
) {
parent.isPresenting.wrappedValue = false
}
func contactViewController(
_ viewController: CNContactViewController,
shouldPerformDefaultActionFor property: CNContactProperty
) -> Bool {
return true
}
}
}