我有一个 scroll 过渡样式UIPageViewController
,仅当设备处于横向时才需要禁用分页。但是应该以纵向启用分页。
我在SO中遇到了类似的问题,但没有遇到我的特定需求。其中一些是:
How do I Disable the swipe gesture of UIPageViewController?
Disable Page scrolling in UIPageViewController
Disable/enable scrolling in UIPageViewController
Restrict UIPageViewController (with TransitionStyleScroll) pan gesture to a certain area
以上所有内容都表示完全禁止或限制平移手势到特定区域。
我将需要找到某些区域
需要计算某些区域(如前所述) 纵向和横向方向都不同
某些用于纵向放置的区域必须是
UIPageViewController
的整个范围
用于横向的某些区域必须是非常小的区域
(其框架可能是0
,0
,1
,1
),用户将无法
执行平移操作。这个帧的计算需要非常
精确,因为我的UIPageViewController
占据了
主屏幕以横向显示。
然后可能再次需要跟踪设备方向的变化 某些区域
作者建议一些技术:
pvc.dataSource = nil // prevents paging
pvc.dataSource = `a valid dataSource object` // enables paging
因此,请手动启用+再次禁用。跟踪方向更改以及启用/禁用。
这对于我的特定用例而言并不安全,因为可能会多次分配数据源。
我认为还有其他方法无法修改以适应用例。
是否有实现我需要的捷径?
答案 0 :(得分:0)
回答了我自己的问题,因为我已经达到了我所需要的。
子类化UIPageViewController
是最简单的方法。我们必须找到页面视图控制器用来处理其平移手势相关工作的基础UIScrollView
。我们将另一个UIPanGestureRecognizer
添加到该内部滚动视图。该平移手势识别器本质上不会执行任何操作,但会阻止内部平移手势识别器仅针对横向识别。
示例实现:
class CustomPageViewController: UIPageViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
if let underlyingScrollView = view.subviews.compactMap({ $0 as? UIScrollView })
.first {
let pangestureRecognizer = UIPanGestureRecognizer()
pangestureRecognizer.delegate = self
underlyingScrollView.addGestureRecognizer(pangestureRecognizer)
// at this point, the underlying scroll view will have two pan gesture
// recognizer side by side. We have the control of our added pan gesture
// recognizer through the delegate. We can conditionally recognize it or not
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer)
-> Bool {
// Returning true from here means, page view controller will behave as it is
// Returning false means, paging will be blocked
// As I needed to block paging only for landscape orientation, I'm just returning
// if orientation is in portrait or not
return UIApplication.shared.statusBarOrientation.isPortrait
}
}