I'm developing an iOS app using SwiftUI with UIKit's UIPageViewController
with UIViewControllerRepresentable and I'm not good with UIKit. I have array of three view controllers which are UIHostingControllers to which I pass my SwiftUI view which is not very simple. When the app launches the second view controller is shown, but UIPageViewController
does not prepare or pre-render the neighboring view controllers until I start swiping. At the moment when I start swiping the next view controller is getting updated (before swipe is finished). This causes a slight glitch on the first swipe that I'd like to avoid. After the first swipe, if I again swipe to that view controller the view update does not happen and further swipes are smooth without any glitches. So how can I prepare the neighbouring views when the app launches, maybe somehow manually render them, idk ...
struct ContentView: UIViewControllerRepresentable {
@ObservedObject var viewModel: ViewModel
var count: Int {
viewModel.dayControllers.count
}
func makeUIViewController(context: Context) -> UIPageViewController {
let pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
pageViewController.dataSource = context.coordinator
pageViewController.delegate = context.coordinator
pageViewController.setViewControllers([viewModel.dayControllers[(count-1)/2]], direction: .forward, animated: false, completion: nil)
return pageViewController
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
// Implementation of ordinary coordinator methods
}
here is view model
class ViewModel: ObservableObject {
@Published var dayControllers: [UIViewController]
//...
init() {
// Initialize dayControllers with view controllers
self.dayControllers = dayVMs.map { dayVM in
UIHostingController(rootView: SomeView(dayVM: dayVM)
.equatable()
)
}
}
}
I tried somehow manually prepare them in makeUIViewController(context: Context) -> UIPageViewController
function like
pageViewController.setViewControllers([viewModel.dayControllers[(count-1)/2]], direction: .forward, animated: true, completion: {_ in
viewModel.dayControllers[(count-1)/2-1].loadViewIfNeeded()
viewModel.dayControllers[(count-1)/2+1].loadViewIfNeeded()
})
Or call before and after methods in the same function
// let _ = context.coordinator.pageViewController(uiViewController, viewControllerBefore: viewModel.dayControllers[(count-1)/2-1])
// let _ = context.coordinator.pageViewController(uiViewController, viewControllerAfter: viewModel.dayControllers[(count-1)/2+1])
But it didn't work.
Maybe there is some straightforward solution, would be happy if someone could help