UITableViewController
包裹的UIViewControllerRepresentable
子类。navigationItem.title
和navigationItem.leftBarButtonItems
。UIViewControllerRepresentable
实例作为SwiftUI NavigationLink
中SwiftUI NavigationView
的目的地。这是怎么回事?
答案 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() }
}