Search code examples
swiftswiftuicontactsui

how solve ContactUI with iOS16 no cancel and done buttons


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
    }
  }
}

enter image description here


Solution

  • 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
        }
      }
    }