UIViewControllerRepresentable:NavigationView中的导航标题和工具栏按钮项

时间:2019-12-11 23:10:11

标签: uiviewcontroller uikit swiftui uinavigationitem navigationview

  • 我有一个UITableViewController包裹的UIViewControllerRepresentable子类。
  • 我已经在视图控制器中设置了navigationItem.titlenavigationItem.leftBarButtonItems
  • 我将UIViewControllerRepresentable实例作为SwiftUI NavigationLink中SwiftUI NavigationView的目的地。
  • 将视图推入导航堆栈时,将显示表格视图,但不显示标题和栏按钮项。

这是怎么回事?

3 个答案:

答案 0 :(得分:0)

解决了!

问题与期望 SwiftUI在后台使用UINavigationController。因此,如果我使用UIViewControllerRepresentable将UIViewController推送到SwiftUI NavigationView上,那么我希望该导航控制器将使用该视图控制器的导航项和工具栏项。正如我上面提到的,它们被忽略了。

根本原因 事实证明,标题和项目被忽略了,因为我的视图控制器的父级不是UINavigationController所期望的。相反,它的父级是SwiftUI在幕后使用的中间包装视图控制器,而后者又被推到导航控制器上。它会忽略标题和项目,因为导航控制器正在向包装器要求其物品(没有包装),而不是我的视图控制器。

UIKit解决方案 因此,如果您想通过UIKit视图控制器设置标题或工具栏按钮项或工具栏项,则需要在其父项上进行设置,例如:

self.parent?.navigationItem.title = “My Title”

此外,您不能从viewDidLoad中执行此操作,因为到那时为止,SwiftUI父级似乎还没有包装视图控制器。您必须在viewWillAppear中完成该操作。

SwiftUI解决方案 您还可以从SwiftUI设置标题和栏按钮。在您的UIViewControllerRepresentable实例上,只需像往常一样添加.navigationBarTitle和开头/结尾项。然后,您可以使按钮从UIViewControllerRepresentable实现中与视图控制器对话。

答案 1 :(得分:0)

josephap 的好的建议,但是他的UIKit解决方案使我的导航栏标题“闪烁”,而不像通常显示的那样平滑。

我的解决方案是从我的SwiftUI添加导航标题:

NavigationLink(destination: <YourUIViewControllerRepresentable>()
                                    .edgesIgnoringSafeArea([.top,.bottom])
                                    .navigationTitle(item.name)) {
                        Text(item.name)
                    }) 

答案 2 :(得分:0)

这是一个 UIKit 解决方案,它不需要对 UIViewController 进行内部更改,并且只应在将包装器添加为父级时调用一次。

struct MyViewControllerRepresentable: UIViewControllerRepresentable {

    class Coordinator {
        var parentObserver: NSKeyValueObservation?
    }

    func makeUIViewController(context: Self.Context) -> MyViewController {
        let viewController =  MyViewController()
        context.coordinator.parentObserver = viewController.observe(\.parent, changeHandler: { vc, _ in
            vc.parent?.title = vc.title
            vc.parent?.navigationItem.rightBarButtonItems = vc.navigationItem.rightBarButtonItems
        })
        return viewController
    }

    func updateUIViewController(_ uiViewController: MyViewController, context: Self.Context) {}

    func makeCoordinator() -> Self.Coordinator { Coordinator() }
}