在 PageViewController 内的 ViewController 内的 ScrollView 中检测滚动偏移量?
Detecting ScrollOffset in ScrollView inside ViewController held within UIPageViewController?
我有一个 UIPageViewController
,其中包含一个 ContentUIViewController
数组,其中包含滚动视图。
当滚动视图滚动时,我想在视图控制器中识别它是 UIPageViewController
的 parent(添加为 child)
实现这一目标的最佳途径是什么?目前我尝试将 didScroll
委派回 ContentUIViewController
的视图模型,然后将其输入 UIPageViewController
的 parent 以调整我想要的 header 高度崩溃,但效果不佳/非常hacky
有没有办法在不通过视图模型反馈的情况下将 child vc 中的委托输出读取到 parent vc?由于 UIPageViewController
而不是单个 child VC.
的数组性质,这被证明是棘手的
已更新:
private func generateContentControllers() -> [UIViewController] {
var viewControllers: [UIViewController] = []
viewControllers.append(ScrollableContentViewController(contentViews: infoViews))
viewControllers.append(reviewsVC)
viewControllers.append(ScrollableContentViewController(contentViews: helpViews))
}
return viewControllers
}
通过
提供
var scrollingViewControllers: [UIViewController] { get }
加上
if let firstViewController = self.viewModel.scrollingViewControllers.first {
pagingController.setViewControllers([firstViewController], direction: .forward, animated: false)
}
以下是如何让它发挥作用。
1. 在 ContentUIViewController
中创建一个 handler
,每个 contentOffset
更改都会在 scrollViewDidScroll(_:)
方法中调用。
class ContentUIViewController: UIViewController, UIScrollViewDelegate {
var handler: ((CGPoint)->())?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
handler?(scrollView.contentOffset)
}
}
2. 在 ParentVC
中,创建 UIPageViewController
的实例并将其添加为 child
。我想你已经这样做了。
接下来您需要做的是创建 ContentUIViewController
的 array
并为每个实例设置我们之前创建的 handler
。
每次 scrollView
在特定 ContentUIViewController
中滚动时都会调用此 handler
。我们将在此处获取 scrollView
的 contentOffset
。用得到的contentOffset
调用updateHeaderHeight(for:)
调整header
高度。
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 {
[=11=].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....
}
我有一个 UIPageViewController
,其中包含一个 ContentUIViewController
数组,其中包含滚动视图。
当滚动视图滚动时,我想在视图控制器中识别它是 UIPageViewController
的 parent(添加为 child)
实现这一目标的最佳途径是什么?目前我尝试将 didScroll
委派回 ContentUIViewController
的视图模型,然后将其输入 UIPageViewController
的 parent 以调整我想要的 header 高度崩溃,但效果不佳/非常hacky
有没有办法在不通过视图模型反馈的情况下将 child vc 中的委托输出读取到 parent vc?由于 UIPageViewController
而不是单个 child VC.
已更新:
private func generateContentControllers() -> [UIViewController] {
var viewControllers: [UIViewController] = []
viewControllers.append(ScrollableContentViewController(contentViews: infoViews))
viewControllers.append(reviewsVC)
viewControllers.append(ScrollableContentViewController(contentViews: helpViews))
}
return viewControllers
}
通过
提供var scrollingViewControllers: [UIViewController] { get }
加上
if let firstViewController = self.viewModel.scrollingViewControllers.first {
pagingController.setViewControllers([firstViewController], direction: .forward, animated: false)
}
以下是如何让它发挥作用。
1. 在 ContentUIViewController
中创建一个 handler
,每个 contentOffset
更改都会在 scrollViewDidScroll(_:)
方法中调用。
class ContentUIViewController: UIViewController, UIScrollViewDelegate {
var handler: ((CGPoint)->())?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
handler?(scrollView.contentOffset)
}
}
2. 在 ParentVC
中,创建 UIPageViewController
的实例并将其添加为 child
。我想你已经这样做了。
接下来您需要做的是创建 ContentUIViewController
的 array
并为每个实例设置我们之前创建的 handler
。
每次 scrollView
在特定 ContentUIViewController
中滚动时都会调用此 handler
。我们将在此处获取 scrollView
的 contentOffset
。用得到的contentOffset
调用updateHeaderHeight(for:)
调整header
高度。
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 {
[=11=].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....
}