// // PDFThumbnailViewController.m // PDFReader // // Copyright © 2014-2022 PDF Technologies, Inc. All Rights Reserved. // // The PDF Reader Sample applications are licensed with a modified BSD license. // Please see License for details. This notice may not be removed from this file. // #import "PDFThumbnailViewController.h" @interface PDFThumbnailView : UIView @property (nonatomic,assign) CGPDFPageRef pageRef; @end @implementation PDFThumbnailView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { CATiledLayer *tiledLayer = (CATiledLayer *)[self layer]; tiledLayer.levelsOfDetail = 4; tiledLayer.levelsOfDetailBias = 4; tiledLayer.tileSize = CGSizeMake(1024.0, 1024.0); } return self; } - (void)dealloc { CATiledLayer *tiledLayer = (CATiledLayer *)[self layer]; tiledLayer.contents = nil; tiledLayer.delegate = nil; [tiledLayer removeFromSuperlayer]; [super dealloc]; } + (Class)layerClass { return [CATiledLayer class]; } + (CFTimeInterval)fadeDuration { return 0.0; } - (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); CGContextFillRect(context, CGContextGetClipBoundingBox(context)); CGContextSaveGState(context); if (!self.pageRef) { return; } CGAffineTransform transform = CGPDFPageGetDrawingTransform(self.pageRef, kCGPDFCropBox, self.bounds, 0, true); CGContextSaveGState(context); CGContextTranslateCTM(context, 0, rect.size.height); CGContextScaleCTM(context, 1, -1); CGContextConcatCTM(context, transform); CGContextSetInterpolationQuality(context, kCGInterpolationLow); CGContextSetRenderingIntent(context, kCGRenderingIntentDefault); CGContextSetShouldAntialias(context, NO); CGContextSetShouldSmoothFonts(context, NO); CGContextDrawPDFPage(context, self.pageRef); CGContextRestoreGState(context); } @end @interface PDFThumbnailViewCell : UICollectionViewCell { PDFThumbnailView *_thumbnailView; } @property (nonatomic,retain) UILabel *textLabel; - (void)setPageRef:(CGPDFPageRef)pageRef; @end @implementation PDFThumbnailViewCell - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { _thumbnailView = [[PDFThumbnailView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height-12)]; _thumbnailView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; _thumbnailView.clipsToBounds = YES; _thumbnailView.layer.borderWidth = 1.0; _thumbnailView.layer.borderColor = [UIColor colorWithRed:214.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0].CGColor; [self.contentView addSubview:_thumbnailView]; _textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, frame.size.height-12, frame.size.width, 12)]; _textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin; _textLabel.textAlignment = NSTextAlignmentCenter; _textLabel.font = [UIFont systemFontOfSize:10]; _textLabel.textColor = [UIColor blackColor]; [self.contentView addSubview:_textLabel]; } return self; } - (void)dealloc { [_thumbnailView release]; [_textLabel release]; [super dealloc]; } - (void)setPageRef:(CGPDFPageRef)pageRef { CGRect boxRect = CGRectZero; if (pageRef) { boxRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox); CGRect displayBounds = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height-12); CGAffineTransform transform = CGPDFPageGetDrawingTransform(pageRef, kCGPDFCropBox, displayBounds, 0, true); boxRect = CGRectApplyAffineTransform(boxRect, transform); } _thumbnailView.frame = boxRect; _thumbnailView.pageRef = pageRef; [_thumbnailView setNeedsDisplay]; } - (void)setSelected:(BOOL)selected { [super setSelected:selected]; if (selected) { _thumbnailView.layer.borderWidth = 1.0; _thumbnailView.layer.borderColor = [UIColor colorWithRed:0.0 green:124.0/255.0 blue:1.0 alpha:1.0].CGColor; self.textLabel.textColor = [UIColor colorWithRed:0.0 green:124.0/255.0 blue:1.0 alpha:1.0]; } else { _thumbnailView.layer.borderWidth = 1.0; _thumbnailView.layer.borderColor = [UIColor colorWithRed:214.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0].CGColor; self.textLabel.textColor = [UIColor blackColor]; } } @end @interface PDFThumbnailViewController () { CGPDFDocumentRef _documentRef; } @property (nonatomic,retain) UICollectionView *collectionView; @end @implementation PDFThumbnailViewController #pragma mark - Init Methods - (void)dealloc { if (_documentRef) { CGPDFDocumentRelease(_documentRef); } _collectionView.delegate = nil; _collectionView.dataSource = nil; [_collectionView release]; [super dealloc]; } #pragma mark - UIViewController Methods - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. UICollectionViewFlowLayout *layout = [[[UICollectionViewFlowLayout alloc] init] autorelease]; layout.itemSize = CGSizeMake(70, 95); layout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5); layout.minimumInteritemSpacing = 5; layout.minimumLineSpacing = 5; self.collectionView = [[[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout] autorelease]; [self.collectionView registerClass:[PDFThumbnailViewCell class] forCellWithReuseIdentifier:@"cell"]; self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; self.collectionView.delegate = self; self.collectionView.dataSource = self; self.collectionView.backgroundColor = [UIColor clearColor]; self.collectionView.alwaysBounceVertical = YES; if (@available(iOS 11.0, *)) { self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways; } [self.view addSubview:self.collectionView]; NSURL *documentURL = [self.pdfViewController.pdfView.document documentURL]; if (documentURL) { _documentRef = CGPDFDocumentCreateWithURL((CFURLRef)documentURL); if ([self.pdfViewController.pdfView.document password]) { CGPDFDocumentUnlockWithPassword(_documentRef, [[self.pdfViewController.pdfView.document password] UTF8String]); } } else { _documentRef = NULL; } } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.collectionView reloadData]; NSInteger pageIndex = [self.pdfViewController.pdfView currentPageIndex]; NSIndexPath *indexPath = [NSIndexPath indexPathForItem:pageIndex inSection:0]; [self.collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionCenteredVertically]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; NSInteger pageIndex = [self.pdfViewController.pdfView currentPageIndex]; NSIndexPath *indexPath = [NSIndexPath indexPathForItem:pageIndex inSection:0]; [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; } #pragma mark - UICollectionViewDataSource - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return CGPDFDocumentGetNumberOfPages(_documentRef); } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { PDFThumbnailViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; CGPDFPageRef pageRef = CGPDFDocumentGetPage(_documentRef, indexPath.item+1); [cell setPageRef:pageRef]; cell.textLabel.text = [NSString stringWithFormat:@"%@",@(indexPath.item+1)]; return cell; } #pragma mark - UICollectionViewDelegate - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { [self dismissViewControllerAnimated:YES completion:^{ [self.pdfViewController.pdfView goToPageIndex:indexPath.item animated:NO]; }]; } @end