仅在 UIPageViewController 上的某个方向上禁用用户滑动?
Posted
技术标签:
【中文标题】仅在 UIPageViewController 上的某个方向上禁用用户滑动?【英文标题】:Disabling User Swipes only in certain direction on UIPageViewController? 【发布时间】:2018-10-04 20:42:40 【问题描述】:我遇到了嵌入在 UIPageViewController 中的 UITableviewController 的问题……系统无法区分向左滑动以更改页面和滑动以删除 UITableView 中的项目。这个特殊的 UITableViewController 恰好在 PageViewController 的最后一页上,所以由于向左滑动并没有真正做任何事情(向右没有任何作用),我可以在当前页面 == 3 时禁用 PageViewController 检测滑动。棘手的部分是我只有想要忽略向左滑动(以便 tableView 将左侧滑动读取为要删除的滑动),而我仍想检测向右滑动以便用户可以导航回第 2 页。
UIPageViewController 代码:
class WorkoutPageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource
//var pageControl = UIPageControl()
var referenceToNewWorkoutKingVC: NewWorkoutKingViewController?
// MARK: UIPageViewControllerDataSource
lazy var orderedViewControllers: [UIViewController] =
var viewControllers = [UIViewController]()
if referenceToNewWorkoutKingVC?.sessionType == goalieSessionString || referenceToNewWorkoutKingVC?.sessionType == refSessionString || referenceToNewWorkoutKingVC?.sessionType == coachSessionString || referenceToNewWorkoutKingVC?.sessionType == openSkateSessionString
viewControllers = [self.newVc(viewController: "NewIceDataTableViewController"),
self.newVc(viewController: "NewHealthDataTableViewController")]
else
viewControllers = [self.newVc(viewController: "NewIceDataTableViewController"),
self.newVc(viewController: "NewHealthDataTableViewController"),
self.newVc(viewController: "NewShiftTableViewController")]
return viewControllers
()
let impact = UIImpactFeedbackGenerator(style: UIImpactFeedbackGenerator.FeedbackStyle.medium)
override func viewDidLoad()
super.viewDidLoad()
self.dataSource = self
self.delegate = self
// This sets up the first view that will show up on our page control
if let firstViewController = orderedViewControllers.first
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
func newVc(viewController: String) -> UIViewController
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
// MARK: Delegate methods
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
let pageContentViewController = pageViewController.viewControllers![0]
referenceToNewWorkoutKingVC?.pageControl.numberOfPages = orderedViewControllers.count
referenceToNewWorkoutKingVC?.pageControl.currentPage = orderedViewControllers.index(of: pageContentViewController)!
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController])
//Haptic when pages switch, code from: https://www.hackingwithswift.com/example-code/uikit/how-to-generate-haptic-feedback-with-uifeedbackgenerator
impact.prepare()
impact.impactOccurred()
// MARK: Data source functions.
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else
return nil
let previousIndex = viewControllerIndex - 1
// User is on the first view controller and swiped left to loop to
// the last view controller.
guard previousIndex >= 0 else
//return orderedViewControllers.last
// Uncommment the line below, remove the line above if you don't want the page control to loop.
return nil
guard orderedViewControllers.count > previousIndex else
return nil
return orderedViewControllers[previousIndex]
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else
return nil
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
// User is on the last view controller and swiped right to loop to
// the first view controller.
guard orderedViewControllersCount != nextIndex else
//return orderedViewControllers.first
// Uncomment the line below, remove the line above if you don't want the page control to loop.
return nil
guard orderedViewControllersCount > nextIndex else
return nil
return orderedViewControllers[nextIndex]
【问题讨论】:
尝试将bounces
属性禁用到false
的UIPageViewController
子视图UIScrollView
如果您的列表在最后一页,它应该可以正常工作,只需检查/验证滑动以删除代码是否到位并且可以正常工作
【参考方案1】:
试试这个
func managePageControllerBounces(isEnable : Bool)
for view in pageViewController.view.subviews
if view is UIScrollView
let scrollView = view as? UIScrollView
scrollView?.bounces = isEnable
根据要求切换退回
self.manegePageControllerBounces(isEnable: false)
希望对你有所帮助....
【讨论】:
谢谢!这确实有点帮助,弹跳的减少使得滑动删除变得更容易一些,但它仍然有点困难并且需要多次尝试。我还能做些什么来让滑动删除更容易吗?感觉好像tableView的cell里面的手势识别器太小了 是的,我添加了这样您就可以看到何时触发了删除操作。以上是关于仅在 UIPageViewController 上的某个方向上禁用用户滑动?的主要内容,如果未能解决你的问题,请参考以下文章
带有 Aspect Fill 图像模式的奇怪 UIPageViewController 滑动行为
UIPageViewController 让 UItalkeViewController 在 iOS 13 上“跳跃”
viewWillAppear 没有在 UIPageViewController 孩子上被调用
如何在 UIPageViewController 上禁用多点触控?