【问题标题】:PDFview scrolls to bottom of the page in single page documentPDFview 在单页文档中滚动到页面底部
【发布时间】:2015-01-24 16:52:26
【问题描述】:

我正在创建一个 PDFViewer 应用程序。 我已将 PDFViewer 的 autoScale 属性设置为 true,以便视图扩展到屏幕的宽度。 适用于大型 PDF 文档。 但是当文档是单页文档时,页面会自动向下滚动到页尾,而不是从头开始。 我只是无法理解它的根本原因。 我在这里错过了什么?

【问题讨论】:

    标签: ios macos cocoa pdfview


    【解决方案1】:

    我认为这是 PDFView 中的一个错误。

    作为解决方法,我建议手动滚动顶部:

    self.pdfView.document = pdfDocument;
    
    NSPoint pt = NSMakePoint(0.0, [self.pdfView.documentView bounds].size.height);
    [self.pdfView.documentView scrollPoint:pt];
    

    错误报告器

    rdar://37942090: PDFview 在单页文档中滚动到页面底部。

    【讨论】:

    • 我发现bug还是存在,你知道iOS11怎么实现吗?
    • iOS 上的 PDFKit 无法访问底层 UIScrollView。但试试这个消息:- (void)goToRect:(PDFRect)rect onPage:(PDFPage *)page; ...我假设 CGRectMake(0,0,1,1) 可能工作
    • No visible @interface for 'UIView' 声明选择器'scrollPoint:'
    【解决方案2】:

    我建议使用此解决方案滚动到首页顶部(适用于 iOS 11.3):

    if let document = pdfView.document,
       let firstPage = document.page(at: 0)
    {
        let firstPageBounds = firstPage.bounds(for: pdfView.displayBox)
        pdfView.go(to: CGRect(x: 0, y: firstPageBounds.height, width: 1.0, height: 1.0), on: firstPage)
    }
    

    【讨论】:

    • 这很接近,但在旋转和/或裁剪的页面上效果不佳。我在下面发布了我的修改。
    • 这似乎不适用于pdfView.autoScale = true。 pdf 总是在第二页的底部打开
    【解决方案3】:

    扩展 Petro 的回答,我在旋转页面和裁剪页面方面遇到了一些问题,但这似乎普遍适用。我实际上在旋转的页面上对其进行了测试,并在角落中添加了注释以验证我选择了正确的角落:

         guard let firstPage = pdfView!.document?.page(at: 0) else {
            return;
         }
         let firstPageBounds = firstPage.bounds(for: pdfView!.displayBox)
         switch (firstPage.rotation % 360) {
         case 0:
            topLeftX = firstPageBounds.minX
            topLeftY = firstPageBounds.maxY
         case 90:
            topLeftX = firstPageBounds.minX
            topLeftY = firstPageBounds.minY
         case 180:
            topLeftX = firstPageBounds.maxX
            topLeftY = firstPageBounds.minY
         case 270:
            topLeftX = firstPageBounds.maxX
            topLeftY = firstPageBounds.maxY
         default:
            print ("Invalid rotation value, not divisible by 90")
         }
    
         pdfView!.go(to: CGRect(x: topLeftX, y: topLeftY, width: 1.0, height: 1.0), on: firstPage)
    

    【讨论】:

    • 很棒的解决方案;在 viewDidLayoutSubviews() 中为我工作
    【解决方案4】:

    看起来go 命令需要在下一次运行时通过运行循环执行才能可靠地工作:

    DispatchQueue.main.async
    {
        guard let firstPage = pdfView.document?.page(at: 0) else { return }
        pdfView.go(to: CGRect(x: 0, y: Int.max, width: 0, height: 0), on: firstPage)
    }
    

    在 iOS 12 上测试

    【讨论】:

      【解决方案5】:

      这就是我做的,有点hacky

      if let scrollView = pdfView.subviews.first as? UIScrollView {
          scrollView.contentOffset.y = 0.0
      }
      

      【讨论】:

        【解决方案6】:

        我在 viewDidLoad 中加载文档,然后将其移至 viewDidAppear,它对我有用。

        【讨论】:

        • 好一个。 viewDidLoad 似乎不是修改屏幕内容的正确位置,因为尚未处理布局...无需在 PDFView 上设置任何偏移或框架,当您第一次在 viewDidAppear 中设置其文档时>
        • 谢谢!这是一条非常重要的信息。
        【解决方案7】:

        对于 Objective-C 使用:

        PDFPage *firstPage = [pdfView.document pageAtIndex:0];
        CGRect firstPageBounds = [firstPage boundsForBox:pdfView.displayBox];
        [pdfView goToRect:CGRectMake(0, firstPageBounds.size.height, 1, 1) onPage:firstPage];
        

        【讨论】:

          【解决方案8】:

          PDFPage 的旋转很重要!这是 Oded 的 Objective-C 版本:

          - (void)scrollToTopOfPage:(PDFPage *)page {
              CGRect pageBounds = [page boundsForBox:self.displayBox];
              CGFloat topLeftX = 0;
              CGFloat topLeftY = 0;
              switch (page.rotation % 360) {
                  case 0:
                      topLeftX = CGRectGetMinX(pageBounds);
                      topLeftY = CGRectGetMaxY(pageBounds);
                      break;
                  case 90:
                      topLeftX = CGRectGetMinX(pageBounds);
                      topLeftY = CGRectGetMinY(pageBounds);
                      break;
                  case 180:
                      topLeftX = CGRectGetMaxX(pageBounds);
                      topLeftY = CGRectGetMinY(pageBounds);
                      break;
                  case 270:
                      topLeftX = CGRectGetMaxX(pageBounds);
                      topLeftY = CGRectGetMaxY(pageBounds);
                      break;
                  default:
                      break;
              }
          
              [self goToRect:CGRectMake(topLeftX, topLeftY, 1, 1) onPage:page];
          }
          

          【讨论】:

            【解决方案9】:
            if let document = PDFDocument(url: viewModel.url) {
                    pdfView.document = document
                    
                    // avoid iOS autoscale issue
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
                        self?.pdfView.autoScales = true
                    }
                }
            

            在加载文档后,我使用变通方法定义了autoScales 属性。那么第一页就很适合放在上面了。

            【讨论】:

              猜你喜欢
              • 2011-05-14
              • 2012-07-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-25
              • 1970-01-01
              相关资源
              最近更新 更多