SwiftUI - CNContactViewController导航栏问题

4

我正在尝试实现CNContactViewDelegate以显示CNContact的详细信息。显然,我是第一个使用SwiftUI实现它并且遇到了问题。无论如何,我可以使用UIViewControllerRepresentable查看CNContact的详细信息,但是我在NavigationBar上遇到了问题,因为NavigationBarNavigationLink之间存在间隙,这会导致Contact的图像和StatusBar之间存在间隙-我认为是这个原因-而且原生的Contacts应用程序中没有这种间隙,这也存在于此链接所实现的UIKit框架中。

以下是代码;

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)都没有起作用。以下是问题的示例,原生应用程序的截图; enter image description here 这是我的代码的结果; enter image description here
2个回答

2

我在解决方案中发表了评论,然后想到将联系人视图控制器包装在我的自定义导航控制器中。嘿,问题解决了!

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

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

是的,日志显示[CNUI WARN] <CNContactViewController: 0x12c0a8a00>被添加到一个不是导航控制器的控制器中,我们将自动更新父导航项<_TtGC7SwiftUIP10$1a254027428DestinationHostingControllerVS_7AnyView_: 0x12ca0fba0>。我想只有苹果才能修复这个小故障。但现在还好,谢谢! - Nico S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接