I've been having issues getting a UIViewControllerRepresentable
wrapping a UIPageViewController
to play nicely with SwiftUI. Specifically, I can't get the searchable
modifier to work properly when the UIViewControllerRepresentable
is in the view hierarchy. This modifier works properly if I replace the UIViewControllerRepresentable
with a TabView
with a .tabViewStyle(.page)
.
Here's some sample code:
import SwiftUI
struct ContentView: View {
@State private var search = ""
var body: some View {
NavigationView {
ControllerPager()
.navigationTitle("Title")
}
.searchable(text: $search)
}
}
struct ControllerPager: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIPageViewController {
UIPageViewController(
transitionStyle: .scroll, navigationOrientation: .horizontal)
}
func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {
pageViewController.setViewControllers(
[UIHostingController(rootView: Page())],
direction: .forward,
animated: true)
}
}
struct NativePager: View {
var body: some View {
TabView {
Page()
}
.tabViewStyle(.page(indexDisplayMode: .never))
}
}
struct Page: View {
var body: some View {
List {
ForEach(0..<100) { i in
Text("\(i)")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
With this code (where I'm not using a TabView
), the searchable
box doesn't appear in the NavigationView
. If I replace the ControllerPager()
with NativePager()
it does.
For those wondering why I'm using UIViewControllerRepresentable
instead of a TabView
, I need a dynamic data source for the UIPageViewController
that updates as the user swipes between pages. I tried this previous answer but the TabView
behaved strangely as I was changing the state while the user was swiping between pages.
Thanks for any help!