PDFKit:设备旋转时PDFView不会调整大小

时间:2018-06-01 16:05:08

标签: ios rotation pdfview

我有一个显示PDFView的iPad应用程序。该应用程序可以旋转到任何方向。 PDFView是全屏和单页。在以任一方向启动时,PDF都会按预期显示;整个第一页可见,缩放以适应屏幕,而不会在屏幕外显示任何PDF。 PDF将始终是一个美国信件大小的文档。

旋转时,PDF会旋转,但不会调整大小。当旋转横向到纵向时,PDF显示为“太小” - 外部有一个巨大的空边框。从纵向到横向旋转时,将显示PDF的前三分之二,底部三分之一丢失在屏幕底部之下。

Autolayout在代码中配置,并且相当直接(顶部,前导,高度和宽度)。

我查看了Reveal中的布局。它显示PDFView实际上是在AutoLayout配置之后正确调整大小。 PDFView内部是一个(私有)PDFDocumentView,它没有调整大小。

我发现“调整大小”视图的唯一方法是在viewWillTransitionToSize中捕获旋转,从superview中删除PDFView,并在将视图重新放入屏幕之前完全重新配置视图(包括重新加载文档)。这是一个糟糕的用户体验。

我将代码解压缩为一个简单的单视图产品。整个UIViewController的代码如下。以下是Reveal显示问题的截图。在这种情况下,我以纵向方式启动了应用程序,旋转了设备,然后拍摄了这些屏幕截图。 (显示的PDF是IRS纳税表;我和应用程序都与IRS无关 - 它恰好是我使用的默认样本PDF。)

#import "ViewController.h"
@import PDFKit;

@interface ViewController ()
@property (nonatomic, strong) PDFView *pdfView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupPDF];
}

-(void)setupPDF {
    NSString *filename = @"myfile.pdf";
    NSString *filenameWithoutPDF = [filename stringByReplacingOccurrencesOfString:@".pdf" withString:@""];
    NSURL *url = [[NSBundle mainBundle] URLForResource:filenameWithoutPDF withExtension:@"pdf"];
    NSData *data = [NSData dataWithContentsOfURL:url];

    self.pdfView = [[PDFView alloc] init];
    PDFDocument *document = [[PDFDocument alloc] initWithData:data];
    self.pdfView.document = document;
    self.pdfView.displayMode = kPDFDisplaySinglePage;
    self.pdfView.autoScales = YES;

    [self.view addSubview:self.pdfView];

    [self setupConstraints];
}

-(void)setupConstraints {
    [self.pdfView setTranslatesAutoresizingMaskIntoConstraints:NO];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.pdfView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.pdfView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.pdfView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.pdfView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];    
}
@end

Private PDFDocumentView has wrong size PDFView has proper layout

2 个答案:

答案 0 :(得分:3)

我发现,至少在某些情况下,autoScales值在旋转时会重置为NO。在WWDC实验室讨论中证实,这似乎是PDFKit中的错误。我已经使用以下代码解决了该错误:

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    self.pdfView.autoScales = YES;
}

我已向Apple提交了该错误;雷达40848802(如果有人想欺骗它)。

答案 1 :(得分:1)

正如Mitch在另一个答案中所述,这绝对是PDFKit框架中的错误。但是,您可能会遇到某些情况,每次设置.autoScales = YES时,应用都会崩溃。例如,当尚未添加文档时。

下面,我添加了一些代码,该代码检查PDFView中是否实际显示了文档,并将.autoScales调用包装到try catch块中。我能够缓解所有崩溃的情况,这些崩溃似乎是从iOS12开始出现的。

就我而言,PDFView尚未直接添加到ViewController中,但实际上是一个子视图。您也可以在fitPDFPage期间致电-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator

- (void)fitPDFPage
{
    if (self.legacyView) return;

    if (@available(iOS 11.0, *))
    {
        if (!self.pdfView.document.pageCount) return;

        self.pdfView.scaleFactor = self.pdfView.scaleFactorForSizeToFit;
        self.pdfView.minScaleFactor = self.pdfView.scaleFactor;

        @try
        {
            self.pdfView.autoScales = YES;
        }
        @catch (NSException *exception)
        {
            NSLog(@"PDFView Exception %@",exception);
        }
    }
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    [self fitPDFPage];
}