PDFThumbnailViewController.m 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. //
  2. // PDFThumbnailViewController.m
  3. // PDFReader
  4. //
  5. // Copyright © 2014-2022 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // The PDF Reader Sample applications are licensed with a modified BSD license.
  8. // Please see License for details. This notice may not be removed from this file.
  9. //
  10. #import "PDFThumbnailViewController.h"
  11. @interface PDFThumbnailView : UIView
  12. @property (nonatomic,assign) CGPDFPageRef pageRef;
  13. @end
  14. @implementation PDFThumbnailView
  15. - (instancetype)initWithFrame:(CGRect)frame {
  16. if (self = [super initWithFrame:frame]) {
  17. CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
  18. tiledLayer.levelsOfDetail = 4;
  19. tiledLayer.levelsOfDetailBias = 4;
  20. tiledLayer.tileSize = CGSizeMake(1024.0, 1024.0);
  21. }
  22. return self;
  23. }
  24. - (void)dealloc {
  25. CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
  26. tiledLayer.contents = nil;
  27. tiledLayer.delegate = nil;
  28. [tiledLayer removeFromSuperlayer];
  29. [super dealloc];
  30. }
  31. + (Class)layerClass {
  32. return [CATiledLayer class];
  33. }
  34. + (CFTimeInterval)fadeDuration {
  35. return 0.0;
  36. }
  37. - (void)drawRect:(CGRect)rect {
  38. [super drawRect:rect];
  39. CGContextRef context = UIGraphicsGetCurrentContext();
  40. CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
  41. CGContextFillRect(context, CGContextGetClipBoundingBox(context));
  42. CGContextSaveGState(context);
  43. if (!self.pageRef) {
  44. return;
  45. }
  46. CGAffineTransform transform = CGPDFPageGetDrawingTransform(self.pageRef,
  47. kCGPDFCropBox,
  48. self.bounds,
  49. 0,
  50. true);
  51. CGContextSaveGState(context);
  52. CGContextTranslateCTM(context, 0, rect.size.height);
  53. CGContextScaleCTM(context, 1, -1);
  54. CGContextConcatCTM(context, transform);
  55. CGContextSetInterpolationQuality(context, kCGInterpolationLow);
  56. CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);
  57. CGContextSetShouldAntialias(context, NO);
  58. CGContextSetShouldSmoothFonts(context, NO);
  59. CGContextDrawPDFPage(context, self.pageRef);
  60. CGContextRestoreGState(context);
  61. }
  62. @end
  63. @interface PDFThumbnailViewCell : UICollectionViewCell {
  64. PDFThumbnailView *_thumbnailView;
  65. }
  66. @property (nonatomic,retain) UILabel *textLabel;
  67. - (void)setPageRef:(CGPDFPageRef)pageRef;
  68. @end
  69. @implementation PDFThumbnailViewCell
  70. - (instancetype)initWithFrame:(CGRect)frame {
  71. if (self = [super initWithFrame:frame]) {
  72. _thumbnailView = [[PDFThumbnailView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height-12)];
  73. _thumbnailView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
  74. _thumbnailView.clipsToBounds = YES;
  75. _thumbnailView.layer.borderWidth = 1.0;
  76. _thumbnailView.layer.borderColor = [UIColor colorWithRed:214.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0].CGColor;
  77. [self.contentView addSubview:_thumbnailView];
  78. _textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, frame.size.height-12, frame.size.width, 12)];
  79. _textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
  80. _textLabel.textAlignment = NSTextAlignmentCenter;
  81. _textLabel.font = [UIFont systemFontOfSize:10];
  82. _textLabel.textColor = [UIColor blackColor];
  83. [self.contentView addSubview:_textLabel];
  84. }
  85. return self;
  86. }
  87. - (void)dealloc {
  88. [_thumbnailView release];
  89. [_textLabel release];
  90. [super dealloc];
  91. }
  92. - (void)setPageRef:(CGPDFPageRef)pageRef {
  93. CGRect boxRect = CGRectZero;
  94. if (pageRef) {
  95. boxRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox);
  96. CGRect displayBounds = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height-12);
  97. CGAffineTransform transform = CGPDFPageGetDrawingTransform(pageRef,
  98. kCGPDFCropBox,
  99. displayBounds,
  100. 0,
  101. true);
  102. boxRect = CGRectApplyAffineTransform(boxRect, transform);
  103. }
  104. _thumbnailView.frame = boxRect;
  105. _thumbnailView.pageRef = pageRef;
  106. [_thumbnailView setNeedsDisplay];
  107. }
  108. - (void)setSelected:(BOOL)selected {
  109. [super setSelected:selected];
  110. if (selected) {
  111. _thumbnailView.layer.borderWidth = 1.0;
  112. _thumbnailView.layer.borderColor = [UIColor colorWithRed:0.0 green:124.0/255.0 blue:1.0 alpha:1.0].CGColor;
  113. self.textLabel.textColor = [UIColor colorWithRed:0.0 green:124.0/255.0 blue:1.0 alpha:1.0];
  114. } else {
  115. _thumbnailView.layer.borderWidth = 1.0;
  116. _thumbnailView.layer.borderColor = [UIColor colorWithRed:214.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0].CGColor;
  117. self.textLabel.textColor = [UIColor blackColor];
  118. }
  119. }
  120. @end
  121. @interface PDFThumbnailViewController () <UICollectionViewDelegate,UICollectionViewDataSource> {
  122. CGPDFDocumentRef _documentRef;
  123. }
  124. @property (nonatomic,retain) UICollectionView *collectionView;
  125. @end
  126. @implementation PDFThumbnailViewController
  127. #pragma mark - Init Methods
  128. - (void)dealloc {
  129. if (_documentRef) {
  130. CGPDFDocumentRelease(_documentRef);
  131. }
  132. _collectionView.delegate = nil;
  133. _collectionView.dataSource = nil;
  134. [_collectionView release];
  135. [super dealloc];
  136. }
  137. #pragma mark - UIViewController Methods
  138. - (void)viewDidLoad {
  139. [super viewDidLoad];
  140. // Do any additional setup after loading the view.
  141. UICollectionViewFlowLayout *layout = [[[UICollectionViewFlowLayout alloc] init] autorelease];
  142. layout.itemSize = CGSizeMake(70, 95);
  143. layout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5);
  144. layout.minimumInteritemSpacing = 5;
  145. layout.minimumLineSpacing = 5;
  146. self.collectionView = [[[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout] autorelease];
  147. [self.collectionView registerClass:[PDFThumbnailViewCell class] forCellWithReuseIdentifier:@"cell"];
  148. self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
  149. self.collectionView.delegate = self;
  150. self.collectionView.dataSource = self;
  151. self.collectionView.backgroundColor = [UIColor clearColor];
  152. self.collectionView.alwaysBounceVertical = YES;
  153. if (@available(iOS 11.0, *)) {
  154. self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAlways;
  155. }
  156. [self.view addSubview:self.collectionView];
  157. NSURL *documentURL = [self.pdfViewController.pdfView.document documentURL];
  158. if (documentURL) {
  159. _documentRef = CGPDFDocumentCreateWithURL((CFURLRef)documentURL);
  160. if ([self.pdfViewController.pdfView.document password]) {
  161. CGPDFDocumentUnlockWithPassword(_documentRef, [[self.pdfViewController.pdfView.document password] UTF8String]);
  162. }
  163. } else {
  164. _documentRef = NULL;
  165. }
  166. }
  167. - (void)viewWillAppear:(BOOL)animated {
  168. [super viewWillAppear:animated];
  169. [self.collectionView reloadData];
  170. NSInteger pageIndex = [self.pdfViewController.pdfView currentPageIndex];
  171. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:pageIndex inSection:0];
  172. [self.collectionView selectItemAtIndexPath:indexPath
  173. animated:NO
  174. scrollPosition:UICollectionViewScrollPositionCenteredVertically];
  175. }
  176. - (void)viewDidAppear:(BOOL)animated {
  177. [super viewDidAppear:animated];
  178. NSInteger pageIndex = [self.pdfViewController.pdfView currentPageIndex];
  179. NSIndexPath *indexPath = [NSIndexPath indexPathForItem:pageIndex inSection:0];
  180. [self.collectionView scrollToItemAtIndexPath:indexPath
  181. atScrollPosition:UICollectionViewScrollPositionCenteredVertically
  182. animated:YES];
  183. }
  184. #pragma mark - UICollectionViewDataSource
  185. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  186. return CGPDFDocumentGetNumberOfPages(_documentRef);
  187. }
  188. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  189. PDFThumbnailViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
  190. CGPDFPageRef pageRef = CGPDFDocumentGetPage(_documentRef, indexPath.item+1);
  191. [cell setPageRef:pageRef];
  192. cell.textLabel.text = [NSString stringWithFormat:@"%@",@(indexPath.item+1)];
  193. return cell;
  194. }
  195. #pragma mark - UICollectionViewDelegate
  196. - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  197. [self dismissViewControllerAnimated:YES completion:^{
  198. [self.pdfViewController.pdfView goToPageIndex:indexPath.item animated:NO];
  199. }];
  200. }
  201. @end