Reputation: 952
I hava a UIPageViewController
that holds an array of ContentUIViewController
, these have scrollviews in them.
When the scrollview scrolls I want to recognise this in the view controller that is the parent of the UIPageViewController
(added as child)
What would be the best route to achieve this? as currently I tried delegating the didScroll
back to the viewmodel for the ContentUIViewController
then feeding that into the parent of the UIPageViewController
to adjust header height that I want to collapse, but it doesn't work well / is very hacky
Is there a way to read delegate output in the a child vc to the parent vc without feeding it back through viewmodels? This is proving tricky due to the array nature of the UIPageViewController
rather than a single child VC.
Updated:
private func generateContentControllers() -> [UIViewController] {
var viewControllers: [UIViewController] = []
viewControllers.append(ScrollableContentViewController(contentViews: infoViews))
viewControllers.append(reviewsVC)
viewControllers.append(ScrollableContentViewController(contentViews: helpViews))
}
return viewControllers
}
Provided via
var scrollingViewControllers: [UIViewController] { get }
Added with
if let firstViewController = self.viewModel.scrollingViewControllers.first {
pagingController.setViewControllers([firstViewController], direction: .forward, animated: false)
}
Upvotes: 0
Views: 273
Reputation: 24341
Here is how you can get that working.
1. Create a handler
in ContentUIViewController
that will be called in scrollViewDidScroll(_:)
method for each contentOffset
change.
class ContentUIViewController: UIViewController, UIScrollViewDelegate {
var handler: ((CGPoint)->())?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
handler?(scrollView.contentOffset)
}
}
2. In ParentVC
, create an instance of UIPageViewController
and add it as a child
to it. I think you did that already.
What you need to do next is create an array
of ContentUIViewController
and for each instance set the handler
that we created earlier.
This handler
will be called every time the scrollView
is scrolled in that particular ContentUIViewController
. We'll get the contentOffset
of the scrollView
here. Call updateHeaderHeight(for:)
with the obtained contentOffset
to adjust the header
height.
class ViewModel {
private func generateContentControllers() -> [ContentUIViewController] {
var viewControllers: [ContentUIViewController] = []
//add your code here....
return viewControllers
}
lazy var scrollingViewControllers: [ContentUIViewController] = {
return self.generateContentControllers()
}()
}
class ParentVC: UIViewController {
let viewModel = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel.scrollingViewControllers.forEach {
$0.handler = {(offset) in
self.updateHeaderHeight(for: offset)
}
}
}
func updateHeaderHeight(for offset: CGPoint) {
//add the code to adjust header height here...
}
//add rest of the code for pageViewController here....
}
Upvotes: 1