ios - 如何仅针对横向禁用 UIPageViewController 的分页?

标签 ios swift uipageviewcontroller uiinterfaceorientation device-orientation

我有一个滚动过渡样式UIPageViewController,仅当设备处于横向时才需要禁用分页。但分页应该在纵向启用。

我在这里遇到了类似的问题,但不是我的具体需求。其中一些是:

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 边界

  • 景观方向的某些区域需要是非常小的区域 (其框架可以是 0011),用户将无法 执行平移操作。这个框架计算需要非常 精确,因为我的 UIPageViewController 占据了整个边界 横向主屏幕。

  • 然后,可能再次需要跟踪不同设备方向的变化 特定区域

  • 的计算
<小时/>

作者建议使用一些技巧:

pvc.dataSource = nil // prevents paging

pvc.dataSource = `a valid dataSource object` // enables paging

因此,再次手动启用+禁用。跟踪方向变化并启用/禁用。

这对于我的特定用例来说并不安全,因为可能会多次分配数据源。

<小时/>

我认为还有其他方法无法修改以适应用例。

有没有捷径可以实现我的需求?

最佳答案

回答我自己的问题,因为我已经实现了我需要的目标。

子类化UIPageViewController是最简单的方法。我们必须找到页面 View Controller 使用的底层 UIScrollView 来处理其平移手势相关的工作。我们将向该内部 ScrollView 添加另一个 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
    }

}

关于ios - 如何仅针对横向禁用 UIPageViewController 的分页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54133232/

相关文章:

ios - 组合这些正则表达式

ios - -[AXSpeechAction 保留] : message sent to deallocated instance 0x1c37e2b0

ios - 如何在Data ViewController的viewDidLoad中加载数据,而不减慢uipageViewController滚动速度?

ios - 使用 UIPageViewController、UIScrollView 的 Xamarin.iOS ScrollView

ios - 在 PageTabViewStyle (SwiftUI 2.0) 或 PageViewController/PageView (带有 UIKit 界面) 上显示部分上一个和下一个项目

ios - Objective-C设置bundle设置值

ios - 是否可以根据国家/地区更改 iPhone 应用程序描述措辞

ios - 你能在 Swift 中创建匿名内部类吗?

swift - 无法将 'SharedSequence<DriverSharingStrategy, Data?>'类型的值转换为预期的参数类型

ios - 如何从 Swift 中的容器 View 获取属性值