PDFKit: PDFView не меняет размер при повороте устройства
У меня есть приложение для iPad, отображающее PDFView. Приложение может вращаться в любой ориентации. PDFView является полноэкранным и одностраничным. PDF отображается, как ожидается, при запуске в любой ориентации; вся первая страница видима, увеличена до размеров экрана, и PDF-файлы не отображаются вне экрана. PDF всегда будет документом размером с букву США.
При повороте PDF-файл поворачивается, но не изменяется. При повороте пейзажа на портрет PDF отображается "слишком маленьким" - с огромной пустой границей вокруг. При повороте портретной / альбомной ориентации отображаются две верхние части PDF-файла, а нижняя треть теряется под нижней частью экрана.
Autolayout настроен в коде и довольно прост (вершина, ведущий, высота и ширина).
Я рассмотрел макет в Reveal. Это показывает, что PDFView фактически изменяет размеры должным образом, следуя конфигурации AutoLayout. Внутри PDFView есть (приватный) PDFDocumentView, который не изменяет размеры.
Единственный способ, с помощью которого я "изменил размер" представления, - это зафиксировать вращение в viewWillTransitionToSize, удалить 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
2 ответа
Я обнаружил, что значение autoScales сбрасывается на NO при вращении, по крайней мере, в некоторых ситуациях. Похоже, что это ошибка в PDFKit, подтвержденная в лабораторной дискуссии WWDC. Я работал над этой ошибкой с помощью этого кода:
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
self.pdfView.autoScales = YES;
}
Я подал ошибку в Apple; Радар 40848802, если кто-то хочет обмануть его.
Как сказал Митч в другом ответе, это определенно ошибка в структуре 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];
}