123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- //
- // PDFPageEditViewController.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 "PDFPageEditViewController.h"
- #import "PDFPageEditCell.h"
- #import <MessageUI/MFMailComposeViewController.h>
- #import "PDFPageEditAddViewController.h"
- @interface PDFPageEditViewController () <UICollectionViewDelegate,UICollectionViewDataSource>
- @property (nonatomic,assign) IBOutlet UICollectionView *collectionView;
- @property (nonatomic,assign) IBOutlet UIToolbar *toolbar;
- @property (nonatomic,retain) NSMutableArray *pages;
- @end
- @implementation PDFPageEditViewController
- #pragma mark - Init Methods
- - (instancetype)init {
- if (self = [super init]) {
-
- }
- return self;
- }
- - (void)dealloc {
- [_pages release];
- [super dealloc];
- }
- #pragma mark - UIViewController Methods
- - (void)viewDidLoad {
- [super viewDidLoad];
-
- // Do any additional setup after loading the view.
- [self setEditing:NO animated:NO];
-
- self.pages = [NSMutableArray array];
- NSURL *documentURL = [self.pdfViewController.pdfView.document documentURL];
- CGPDFDocumentRef documentRef = CGPDFDocumentCreateWithURL((CFURLRef)documentURL);
- if ([self.pdfViewController.pdfView.document password]) {
- CGPDFDocumentUnlockWithPassword(documentRef, [[self.pdfViewController.pdfView.document password] UTF8String]);
- }
- NSInteger pagesCount = CGPDFDocumentGetNumberOfPages(documentRef);
- for (int i = 0; i < pagesCount; i++) {
- CGPDFPageRef pageRef = CGPDFDocumentGetPage(documentRef, i+1);
- PDFEditPage *page = [[PDFEditPage alloc] initWithPageRef:pageRef];
- [self.pages addObject:page];
- [page release];
- }
- CGPDFDocumentRelease(documentRef);
-
- [self.collectionView registerClass:[PDFPageEditCell class] forCellWithReuseIdentifier:@"PDFPageEditCell"];
- self.collectionView.alwaysBounceVertical = YES;
-
- UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlelongGesture:)];
- [self.collectionView addGestureRecognizer:longGesture];
- [longGesture release];
- }
- - (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear:animated];
-
- 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];
- }
- - (void)updateTitle {
- if (self.isEditing) {
- NSInteger count = [self.collectionView indexPathsForSelectedItems].count;
- self.title = [NSString stringWithFormat:@"%@ %ld",NSLocalizedString(@"Selected:", nil), (long)count];
- } else {
- self.title = nil;
- }
- }
- - (void)reloadDataVisibleCells {
- for (PDFPageEditCell *cell in [self.collectionView visibleCells]) {
- NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
- cell.textLabel.text = [NSString stringWithFormat:@"%@",@(indexPath.item+1)];
- }
- }
- #pragma mark - Button Actions
- - (void)setEditing:(BOOL)editing animated:(BOOL)animated {
- [super setEditing:editing animated:animated];
- if (editing) {
- self.collectionView.allowsMultipleSelection = YES;
-
- UIBarButtonItem *selectAllItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"selectall.png"] style:UIBarButtonItemStylePlain target:self action:@selector(buttonItemClicked_SelectAll:)];
- if (UIUserInterfaceIdiomPad == UI_USER_INTERFACE_IDIOM()) {
- NSMutableArray *items = [NSMutableArray array];
- [self.toolbar.items enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(UIBarButtonItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
- if (obj.target) {
- [items addObject:obj];
- }
- }];
- [items addObject:selectAllItem];
- [self.navigationItem setRightBarButtonItems:items animated:animated];
- } else {
- [UIView animateWithDuration:animated ? 0.3 : 0.0 animations:^{
- self.toolbar.alpha = 1.0;
- }];
-
- [self.navigationItem setLeftBarButtonItems:@[selectAllItem] animated:animated];
-
- UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(buttonItemClicked_Done:)];
- [self.navigationItem setRightBarButtonItems:@[doneItem] animated:animated];
- [doneItem release];
- }
- [selectAllItem release];
- } else {
- self.collectionView.allowsMultipleSelection = NO;
- [UIView animateWithDuration:animated ? 0.3 : 0.0 animations:^{
- self.toolbar.alpha = 0.0;
- }];
-
- UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(buttonItemClicked_Done:)];
- [self.navigationItem setLeftBarButtonItems:@[doneItem] animated:animated];
- [doneItem release];
-
- UIBarButtonItem *editItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(buttonItemClicked_Edit:)];
- [self.navigationItem setRightBarButtonItems:@[editItem] animated:animated];
- [editItem release];
- }
- [self updateTitle];
- }
- - (void)buttonItemClicked_Done:(id)sender {
- if (self.isEditing) {
- [self setEditing:NO animated:YES];
- } else {
- [self dismissViewControllerAnimated:YES completion:^{
- [self.pdfViewController.pdfView.document writeToURL:self.pdfViewController.pdfView.document.documentURL];
- [self.pdfViewController loadDocumentWithFilePath:self.pdfViewController.filePath completion:nil];
- }];
- }
- }
- - (void)buttonItemClicked_Edit:(id)sender {
- [self setEditing:YES animated:YES];
- }
- - (void)buttonItemClicked_SelectAll:(id)sender {
- BOOL isSelectAll = NO;
- if ([self.collectionView indexPathsForSelectedItems].count != [self.collectionView numberOfItemsInSection:0]) {
- isSelectAll = YES;
- }
- for (int i=0; i<[self.collectionView numberOfItemsInSection:0]; i++) {
- NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
- if (isSelectAll) {
- [self.collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];
- } else {
- [self.collectionView deselectItemAtIndexPath:indexPath animated:YES];
- }
- }
- [self updateTitle];
- }
- - (IBAction)buttonItemClicked_Add:(id)sender {
- PDFPageEditAddViewController *vc = [[PDFPageEditAddViewController alloc] init];
- vc.callback = ^(PDFEditPage *page) {
- NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.pdfViewController.pdfView.currentPageIndex+1
- inSection:0];
- [self.pages insertObject:page atIndex:indexPath.item];
- [self.collectionView insertItemsAtIndexPaths:@[indexPath]];
- if (page.imagePath) {
- [self.pdfViewController.pdfView.document insertPage:page.size withImage:page.imagePath atIndex:indexPath.item];
- } else {
- [self.pdfViewController.pdfView.document insertPage:page.size atIndex:indexPath.item];
- }
- [self reloadDataVisibleCells];
- };
- [vc showViewController:self inBarButtonItem:sender];
- [vc release];
- }
- - (IBAction)buttonItemClicked_Extract:(id)sender {
- NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
- NSString *fileName = self.pdfViewController.pdfView.document.documentURL.lastPathComponent.stringByDeletingPathExtension;
- NSString *filePath = [NSString stringWithFormat:@"%@/%@_Pages.pdf",path,fileName];
- NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
- for (NSIndexPath *indexPath in [self.collectionView indexPathsForSelectedItems]) {
- [indexSet addIndex:indexPath.item];
- }
-
- CPDFDocument *document = [[[CPDFDocument alloc] init] autorelease];
- [document importPages:indexSet fromDocument:self.pdfViewController.pdfView.document atIndex:0];
- [document writeToURL:[NSURL fileURLWithPath:filePath]];
-
- NSString *message = [NSString stringWithFormat:NSLocalizedString(@"This file has been saved in:'Documents/'", nil)];
- UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
- style:UIAlertActionStyleCancel
- handler:nil];
- UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Successfully!", nil)
- message:message
- preferredStyle:UIAlertControllerStyleAlert];
- [alert addAction:cancelAction];
- [self presentViewController:alert animated:YES completion:nil];
- }
- - (IBAction)buttonItemClicked_Rotate:(id)sender {
- NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
- for (NSIndexPath *indexPath in [self.collectionView indexPathsForSelectedItems]) {
- PDFPageEditCell *cell = (PDFPageEditCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
- PDFEditPage *page = [self.pages objectAtIndex:indexPath.item];
- page.rotation += 90;
- if (page.rotation == 360) {
- page.rotation = 0;
- }
- cell.page = page;
- [indexSet addIndex:indexPath.item];
-
- CPDFPage *pPage = [self.pdfViewController.pdfView.document pageAtIndex:indexPath.item];
- pPage.rotation += 90;
- }
- }
- - (IBAction)buttonItemClicked_Mail:(id)sender {
- NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
- NSString *fileName = self.pdfViewController.pdfView.document.documentURL.lastPathComponent.stringByDeletingPathExtension;
- NSString *filePath = [NSString stringWithFormat:@"%@/%@_Pages.pdf",path,fileName];
- NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
- for (NSIndexPath *indexPath in [self.collectionView indexPathsForSelectedItems]) {
- [indexSet addIndex:indexPath.item];
- }
-
- CPDFDocument *document = [[[CPDFDocument alloc] init] autorelease];
- [document importPages:indexSet fromDocument:self.pdfViewController.pdfView.document atIndex:0];
- [document writeToURL:[NSURL fileURLWithPath:filePath]];
-
- MFMailComposeViewController *vc = [[MFMailComposeViewController alloc] init];
- vc.mailComposeDelegate = (id)self;
- [vc addAttachmentData:[NSData dataWithContentsOfFile:filePath]
- mimeType:[NSString stringWithFormat:@"application/%@",[filePath pathExtension]]
- fileName:[filePath lastPathComponent]];
- [self presentViewController:vc animated:YES completion:nil];
- [vc release];
- }
- - (IBAction)buttonItemClicked_Delete:(id)sender {
- NSInteger selectedCount = [self.collectionView indexPathsForSelectedItems].count;
- NSInteger totalCount = [self.collectionView numberOfItemsInSection:0];
- if (selectedCount == totalCount) {
- UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
- style:UIAlertActionStyleCancel
- handler:nil];
- UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Warning", nil)
- message:NSLocalizedString(@"Can not delete all pages.", nil)
- preferredStyle:UIAlertControllerStyleAlert];
- [alert addAction:cancelAction];
- [self presentViewController:alert animated:YES completion:nil];
- return;
- }
-
- NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
- for (NSIndexPath *indexPath in [self.collectionView indexPathsForSelectedItems]) {
- [indexSet addIndex:indexPath.item];
- }
- [self.pages removeObjectsAtIndexes:indexSet];
- [self.collectionView deleteItemsAtIndexPaths:[self.collectionView indexPathsForSelectedItems]];
- [self.pdfViewController.pdfView.document removePageAtIndexSet:indexSet];
- [self reloadDataVisibleCells];
- }
- #pragma mark - UICollectionViewDelegateFlowLayout
- - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
- NSInteger count = 4;
- UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)collectionViewLayout;
- CGFloat width = MIN(self.view.bounds.size.width, self.view.bounds.size.height);
- width -= (count-1)*flowLayout.minimumInteritemSpacing;
- width -= flowLayout.sectionInset.left;
- width -= flowLayout.sectionInset.right;
- width /= count;
- return CGSizeMake(width, width+18);
- }
- #pragma mark - UICollectionViewDataSource
- - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
- return self.pages.count;
- }
- - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
- PDFPageEditCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PDFPageEditCell" forIndexPath:indexPath];
- cell.backgroundColor = [UIColor clearColor];
- cell.page = self.pages[indexPath.item];
- cell.textLabel.text = [NSString stringWithFormat:@"%@",@(indexPath.item+1)];
- return cell;
- }
- #pragma mark - UICollectionViewDelegate
- - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
- [self updateTitle];
- if (!self.isEditing) {
- [self dismissViewControllerAnimated:YES completion:^{
- [self.pdfViewController.pdfView.document writeToURL:self.pdfViewController.pdfView.document.documentURL];
- [self.pdfViewController loadDocumentWithFilePath:self.pdfViewController.filePath completion:^(BOOL result) {
- if (result) {
- [self.pdfViewController.pdfView goToPageIndex:indexPath.item animated:NO];
- }
- }];
- }];
- }
- }
- - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
- [self updateTitle];
- }
- #pragma mark - UICollectionView Draggable
- - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath {
- return YES;
- }
- - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath {
- if (sourceIndexPath.item != destinationIndexPath.item) {
- CPDFPage *page = [[self.pages objectAtIndex:sourceIndexPath.item] retain];
- [self.pages removeObject:page];
- [self.pages insertObject:page atIndex:destinationIndexPath.item];
- [page release];
- [self.pdfViewController.pdfView.document movePageAtIndex:sourceIndexPath.item withPageAtIndex:destinationIndexPath.item];
- [self reloadDataVisibleCells];
- }
- }
- - (void)handlelongGesture:(UILongPressGestureRecognizer *)longGesture {
- switch (longGesture.state) {
- case UIGestureRecognizerStateBegan:
- {
- NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[longGesture locationInView:self.collectionView]];
- if (indexPath == nil) {
- break;
- }
- [self.collectionView beginInteractiveMovementForItemAtIndexPath:indexPath];
- [UIView animateWithDuration:0.2 animations:^{
- [self.collectionView updateInteractiveMovementTargetPosition:[longGesture locationInView:self.collectionView]];
- }];
- }
- break;
- case UIGestureRecognizerStateChanged:
- {
- [self.collectionView updateInteractiveMovementTargetPosition:[longGesture locationInView:self.collectionView]];
- }
- break;
- case UIGestureRecognizerStateEnded:
- {
- [self.collectionView endInteractiveMovement];
- }
- break;
- default:
- {
- [self.collectionView cancelInteractiveMovement];
- }
- break;
- }
- }
- #pragma mark - MFMailComposeViewControllerDelegate
- - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error {
- [controller dismissViewControllerAnimated:YES completion:nil];
- }
- @end
|