问题描述
在以下情况下,我试图实现连续滚动:
MainViewController(UIViewController
)包含一个UIPageViewController
(transitionStyle: .scroll
)的实例,该实例仅管理两个控制器。 ItemsViewController(UIViewController
)和ProfileViewController(UIViewController
)。 MainViewController允许在主控制器和配置文件控制器之间水平滚动。
现在,ProfileViewController包含UIPageViewController
(transitionStyle: .scroll
)的另一个实例,可以在两个UIViewController
(A和B)之间水平滚动。
问题是,当我滚动到ProfileViewController并开始在A和B之间滚动时,我无法滚动(向右)返回到ItemsViewController。似乎ProfileViewController的UIPageViewController
正在拦截滚动手势,并且没有将它们传递给MainViewController的UIPageViewController
实例,您将陷入ProfileViewController中。
这是一些代码:
final class MainViewController: UIViewController {
private let pageController: UIPageViewController
let itemsController: ItemsViewController
let profileController: ProfileViewController
private var controllers = [UIViewController]()
private(set) var currentPageIndex = 0
override init(...) {
itemsController = ItemsViewController(...)
controllers.append(itemsController)
profileController = ProfileViewController(...)
controllers.append(profileController)
pageController = UIPageViewController(transitionStyle: .scroll,navigationorientation: .horizontal,options: nil)
super.init(...)
}
override func viewDidLoad() {
super.viewDidLoad()
configurePageController()
}
func configurePageController() {
pageController.dataSource = self
pageController.delegate = self
pageController.setViewControllers([itemsController],direction: .forward,animated: false)
for view in pageController.view.subviews {
if let scrollView = view as? UIScrollView {
scrollView.delegate = self
break
}
}
}
}
extension MainViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController,viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController) {
if index > 0 {
return controllers[index - 1]
}
else {
return nil
}
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController,viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController) {
if index < controllers.count - 1 {
return controllers[index + 1]
}
else {
return nil
}
}
return nil
}
}
extension MainViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController,didFinishAnimating finished: Bool,prevIoUsViewControllers: [UIViewController],transitionCompleted completed: Bool) {
guard completed else {
return
}
if let vc = pageController.viewControllers?.first,let index = controllers.firstIndex(of: vc) {
currentPageIndex = index
}
}
}
// Freeze scrolling on the left and right edges
extension MainViewController: uiscrollviewdelegate {
private func freezScrolling(_ scrollView: UIScrollView) {
if currentPageIndex == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width {
scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width,y: 0)
}
else if currentPageIndex == controllers.count - 1 && scrollView.contentOffset.x > scrollView.bounds.size.width {
scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width,y: 0)
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
freezScrolling(scrollView)
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView,withVeLocity veLocity: CGPoint,targetContentOffset: UnsafeMutablePointer<CGPoint>) {
freezScrolling(scrollView)
}
}
final class ProfileViewController: UIViewController {
private let pageController: UIPageViewController
private lazy var controllers: [UIViewController] = [ControllerA,ControllerB]
private var currentPageIndex = 0
override init(...) {
pageController = UIPageViewController(transitionStyle: .scroll,options: nil)
super.init(...)
}
override func viewDidLoad() {
super.viewDidLoad()
configurePageController()
}
func configurePageController() {
pageController.dataSource = self
pageController.delegate = self
for view in pageController.view.subviews {
if let scrollView = view as? UIScrollView {
scrollView.delegate = self
break
}
}
}
extension ProfileViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController,viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController),index > 0 {
return controllers[index - 1]
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController,viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let index = controllers.firstIndex(of: viewController),index < controllers.count - 1 {
return controllers[index + 1]
}
return nil
}
}
extension ProfileViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController,transitionCompleted completed: Bool) {
guard completed else {
return
}
if let vc = pageController.viewControllers?.first,let index = controllers.firstIndex(of: vc) {
currentPageIndex = index
}
}
}
extension ProfileViewController: uiscrollviewdelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
freezScrolling(scrollView)
}
private func freezScrolling(_ scrollView: UIScrollView) {
if currentPageIndex == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width {
scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width,y: 0)
}
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView,targetContentOffset: UnsafeMutablePointer<CGPoint>) {
freezScrolling(scrollView)
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)