2

我正在尝试实现CNContactViewDelegate能够显示CNContact. 显然,我是第一个实施它SwiftUI并遇到问题的人。无论如何,我可以看到使用的细节,CNContactUIViewControllerRepresentable我有一个问题,在图像和之间NavigationBar存在差距-因为我认为-并且本机应用程序中不存在这种差距,显然在这个中实现框架的链接ContactStatusBarNavigationBarNavigationLinkContactsUIKit

这是代码;

struct ContactsListView: View {
    @ObservedObject var contactsModel: ContactsViewModel
    var body: some View {
        NavigationView{
            List {
                //After some ForEach's and Section's
                //This view is working. 
                NavigationLink(destination: ContactDetailView(contact: self.$contactsModel.contacts[sectionIdx].contacts[contactIdx])) {
                    Text(self.contactsModel.contacts[sectionIdx].contacts[contactIdx].givenName)
                }
            }
            .navigationBarTitle("Contacts")
        }
    }
}


struct ContactView: UIViewControllerRepresentable {

    @Binding var contact: CNContact

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

    func makeUIViewController(context: UIViewControllerRepresentableContext<ContactView>) -> CNContactViewController {
        let controller = CNContactViewController(for: contact)
        self.navigationBarHidden(true)
        return controller
    }

    func updateUIViewController(_ uiViewController: CNContactViewController, context: UIViewControllerRepresentableContext<ContactView>) {
        print(context)
    }

    class Coordinator: NSObject, CNContactViewControllerDelegate {

        var parent: ContactView

        init(_ contactDetail: ContactView) {
            self.parent = contactDetail
            self.parent.navigationBarHidden(true)

        }
    }
}

在 中ContactView,这两个self.navigationBarHidden(true)都不起作用。此处的问题示例是本机应用程序的屏幕截图;

在此处输入图像描述

这是我的代码的结果;

在此处输入图像描述

4

2 回答 2

2

发表了我对解决方案的评论,然后我想到将联系人视图控制器包装在我的自定义 NavigationController 中。瞧,修复了它!

struct ContactView: UIViewControllerRepresentable {

    var contact: CNContact

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

    func makeUIViewController(context: UIViewControllerRepresentableContext<ContactView>) -> NavigationController {
        let controller = CNContactViewController(forUnknownContact: contact)
        controller.contactStore = CNContactStore()
        controller.delegate = context.coordinator
        let navigationController = NavigationController(rootViewController: controller)
        return navigationController
    }

    func updateUIViewController(_ uiViewController: NavigationController, context: UIViewControllerRepresentableContext<ContactView>) {
    }

    class Coordinator: NSObject, CNContactViewControllerDelegate {

        var parent: ContactView

        init(_ contactDetail: ContactView) {
            self.parent = contactDetail
        }

        func contactViewController(_ viewController: CNContactViewController,
                                   didCompleteWith contact: CNContact?) {
        }

        func contactViewController(_ viewController: CNContactViewController,
                                   shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
            return true
        }
    }
}
于 2021-05-09T00:15:20.653 回答
1

由于这个问题得到了赞成,我想我可以分享我的中途解决方案。这解决了差距,但是在过渡到细节的过程中,导航栏的背景颜色会出现故障。过渡之后,它变得清晰起来。

struct ContactDetailView:  View {

    var contact: CNContact

    var body: some View {
        ZStack {
            Color.clear
            ContactView(contact: self.contact)
                .navigationBarTitle("", displayMode: .inline)
        }.edgesIgnoringSafeArea(.top)
    }
}

struct ContactView: UIViewControllerRepresentable {

    var contact: CNContact

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

    func makeUIViewController(context: UIViewControllerRepresentableContext<ContactView>) -> CNContactViewController {
        let controller = CNContactViewController(forUnknownContact: contact)
        controller.allowsActions = true
        controller.allowsEditing = false
        controller.delegate = context.coordinator
        return controller
    }

    func updateUIViewController(_ uiViewController: CNContactViewController, context: UIViewControllerRepresentableContext<ContactView>) {
        print("updated")
    }

    class Coordinator: NSObject, CNContactViewControllerDelegate {

        var parent: ContactView

        init(_ contactDetail: ContactView) {
            self.parent = contactDetail
        }

        func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
        }

        func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {

            return true
        }
    }
}
于 2020-06-18T10:19:59.107 回答