1

When I press Edit from contact card, my CNContactViewController is not showing the delete option in the bottom of the screen.

NB: the button remains shown for iOS 13.

screenshot

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
  • Is the button possibly displaying off screen, have you tried wrapping the view in a UIScrollView if using UIKit? – will Oct 19 '20 at 21:20
  • When I debug the UI or try to scroll more down, the button doesn't show. I'm pretty sure it's not there. – lilia belkahla Oct 20 '20 at 13:47
  • Might be worth sharing you code, to see if someone can spot an issue there. – will Oct 20 '20 at 13:59
  • I posted an answer, you can check. I'm pushing the contactviewcontroller from a SwiftUI view, so I'm using a UIViewControllerRepresentable and check my second answer to see how I push. thanks for helping :) – lilia belkahla Oct 20 '20 at 17:13

2 Answers2

1
import Foundation
import ContactsUI
import SwiftUI

struct CNContactViewControllerRepresentable: UIViewControllerRepresentable {
typealias UIViewControllerType = CNContactViewController
    var contact: Binding<CNContact>
    var presentingEditContact: Binding<Bool>

    func makeCoordinator() -> CNContactViewControllerRepresentable.Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<CNContactViewControllerRepresentable>) -> CNContactViewControllerRepresentable.UIViewControllerType {
        let controller = CNContactViewController(forNewContact: contact.wrappedValue)
        controller.delegate = context.coordinator
        return controller
    }

    func updateUIViewController(_ uiViewController: CNContactViewControllerRepresentable.UIViewControllerType, context: UIViewControllerRepresentableContext<CNContactViewControllerRepresentable>) {
        //
    }

    // Nested coordinator class, the prefered way stated in SwiftUI documentation.
    class Coordinator: NSObject, CNContactViewControllerDelegate {
        var parent: CNContactViewControllerRepresentable

        init(_ contactDetail: CNContactViewControllerRepresentable) {
            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
        }
    }
}
  • Is it because of calling forNewContact? Do you need to call https://developer.apple.com/documentation/contactsui/cncontactviewcontroller/1616927-init for existing contacts? Sorry not at my computer to check. – will Oct 20 '20 at 18:21
0
.sheet(isPresented: $viewModel.presentingEditContact) {
            NavigationView {
                if #available(iOS 14, *) {
                    return AnyView(CNContactViewControllerRepresentable(contact: self.$viewModel.contact, presentingEditContact: $viewModel.presentingEditContact)
                        .navigationBarTitle("Edit Contact")
                        .edgesIgnoringSafeArea(.top))
                } else {
                    return AnyView(CNContactViewControllerRepresentable(contact: self.$viewModel.contact, presentingEditContact: $viewModel.presentingEditContact)
                        .edgesIgnoringSafeArea(.top))
                }
            }
        }