ios - 在特定 iPad 型号上添加 UIView Laggy

标签 ios swift ipad uiview lag

我有一个乐谱的 pdf 查看器,它基于 PDFKit。 PDFKit 可以选择使用内部 UIPageViewController,但这是一个很大的问题 - 您无法设置转换类型,更糟糕的是,无法检查页面滑动是否成功或失败。您最终会看到一页,而报告的页面索引是另一页。

因此我决定创建自己的翻页方法。我添加了一个 UITapGestureRecognizer,当点击右边缘或左边缘时,页面会以编程方式翻转。为了实现 curl 动画,我添加了一个与其下方具有相同图像的 UIView,对 PDFView 执行 curl 动画,然后删除该 View 。这是部分代码:

// Function to flip pages with page curl
    func flipPage (direction: String) {
        let renderer = UIGraphicsImageRenderer(size: pdfView.bounds.size)
        let image = renderer.image { ctx in
            pdfView.drawHierarchy(in: pdfView.bounds, afterScreenUpdates: true)
        }
        let imageView = UIImageView(image: image)
        imageView.frame = pdfView.frame
        imageView.tag = 830
        self.view.addSubview(imageView)
        self.view.bringSubviewToFront(imageView)

        if direction == "forward" && pdfView.canGoToNextPage() {
            pdfView.goToNextPage(nil)
            let currentImageView = self.view.subviews.filter({$0.tag == 830})
            if currentImageView.count > 0 {
                UIView.transition(from: currentImageView[0],
                                  to: pdfView, duration: 0.3,
                                  options: [.transitionCurlUp, .allowUserInteraction],
                                  completion: {finished in
                                    currentImageView[0].removeFromSuperview()
                })
            }
        }

现在奇怪的部分来了。在我自己的 iPad Pro 12.9 英寸第一代上,这种翻转方法速度非常快。无论构建配置或优化级别如何,它都可以正常工作。如果我快速连续点击,页面就会随着我点击的速度快速翻动。

我的用户使用的是第二代 iPad Pro 12.9,当 UIView 绘制在 PDFView 之上时,他们遇到了严重的延迟。这种情况也会发生在所有构建配置上 - 它发生在发布构建中,并且当我在这样的设备上从我的计算机安装调试构建时也会发生这种情况(遗憾的是,我无法让设备进一步探索)。

应用程序中还有其他几个实例,我在顶部添加了 UIView - 添加半透明的面纱,或捕获 UIGestureRecognizers。在我自己的设备上,这些都非常快。在第二代 iPad 上,每一项都会导致延迟。顺便说一句,一位使用第三代 iPad Pro 的用户报告说,他的设备上的性能非常快,没有任何延迟。在模拟器上,动画有时不完整,但对于所有 iPad 型号来说,响应速度都足够快。

我搜索了答案,但发现完全没有提到这种奇怪的情况。有人经历过这样的事情吗?我的代码逻辑中有任何快速修复或明显的问题吗?

我担心,如果我尝试提前绘制自定义 UIView,并且只在需要时将它们带到前面,我最终会在后台得到大量可笑的 UIView,并且只需移动延迟其他地方。

最佳答案

经过一些研究,我可以为面临类似问题的人提供解决方案。问题似乎出在日程安排上。

  1. 我仍然不知道为什么 2017 年的模型会以不同的方式调度它们的线程。欢迎任何关于为什么这个问题首先出现的想法。然而-
  2. 事实上,我并没有遵循最佳实践。 UI 的更改应该始终发生在主线程中,因此如果遇到这样的延迟,请像这样封装 UIView 的实际添加和删除:

    DispatchQueue.main.async {
        self.view.addSubview(imageView)
        self.view.bringSubviewToFront(imageView)
    }
    

    我的用户报告问题在那之后就消失了。

编辑

确保将 UIView 和动画 block 添加到同一个 DispatchQueue 段中,否则它们将竞争执行槽。我的最终代码如下所示:

func flipPage (direction: String) {
        let renderer = UIGraphicsImageRenderer(size: pdfView.bounds.size)
        let image = renderer.image { ctx in
            pdfView.drawHierarchy(in: self.pdfView.bounds, afterScreenUpdates: true)
        let imageView = UIImageView(image: image)
        imageView.frame = pdfView.frame

        if direction == "forward" && pdfView.canGoToNextPage() {
            DispatchQueue.main.async {
                self.view.addSubview(imageView)
                self.view.bringSubviewToFront(imageView)
                self.pdfView.goToNextPage(nil)
                UIView.transition(from: imageView,
                                  to: self.pdfView, duration: 0.3,
                                  options: [.transitionCurlUp, .allowUserInteraction],
                                  completion: {finished in
                                    imageView.removeFromSuperview()
                })
            }
        }

附言如果可能,请避免使用drawHierarchy - 它不是一个非常快的方法。

  • 无论如何,如果您需要针对特定​​设备进行不同的编码,请查看 DeviceKit 。一个很棒的项目,为您提供了尽可能简单的界面。
  • 关于ios - 在特定 iPad 型号上添加 UIView Laggy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54904931/

    相关文章:

    ios - Swift:在不同设备上以编程方式查找元素的大小

    ios - 我有一个 Storyboard,我插入这个。我想在启动 Controller 之前在 Storyboard上获取控件的名称。如何?

    ios - Realm swift : Is it possible to keep database after the apps is uninstalled?

    ios - 如何在 swift 应用程序中存储表单数据

    ios - 为什么关闭 UIAlertController 会调用 UINavigationController 上的关闭?

    objective-c - 如何做 iPad Photos app pinch to expand

    ios - 为什么我应该使自定义协议(protocol)符合 NSObject?

    ios - 自动 ARC 转换后 : Assigning retained object to unsafe property; object will be released after assignment

    ios - Swift 3 请求 post ,响应返回 nil

    iphone - 使用 ShareKit 将图像发布到 Facebook