PDFViewController.m 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726
  1. //
  2. // PDFViewController.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 "PDFViewController.h"
  11. #import "PDFNoteViewController.h"
  12. #import "PDFColorViewController.h"
  13. #import "PDFShapeViewController.h"
  14. #import "PDFStampViewController.h"
  15. #import "PDFLinkViewController.h"
  16. #import "PDFSignatureViewController.h"
  17. #import "PDFViewerModeViewController.h"
  18. #import "PDFSearchViewController.h"
  19. #import "PDFBOTAViewController.h"
  20. #import "PDFPageEditViewController.h"
  21. #import <ComPDFKit/CPDFWatermark.h>
  22. #import <ComPDFKit/CPDFHeaderFooter.h>
  23. #import "PDFWatermarkDataModel.h"
  24. #import "PDFHeaderFooterAddController.h"
  25. #import "PDFBatesAddViewController.h"
  26. #import "PDFHeaderFooterSettingView.h"
  27. #import "PDFBackgroundSettingViewController.h"
  28. #import "PDFBackgroundModel.h"
  29. #import "PDFAddWaterMarkViewController.h"
  30. #import "PDFWatermarkTextPreview.h"
  31. #import "PDFWatermarkImagePreview.h"
  32. #import "PDFToolbar.h"
  33. #import "PDFFreehandView.h"
  34. #import "PDFSlider.h"
  35. #import "PDFBottomToolbar.h"
  36. #import "PDFTitleView.h"
  37. #import "PDFKeyboardToolbar.h"
  38. @interface PDFViewController () <UIPopoverPresentationControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, CPDFViewDelegate, PDFListViewDelegate, PDFKeyboardDelegate, PDFModelDataDelegate, BackgroundDataModelDelegate, WaterMarkModelDataDelegate>
  39. @property (nonatomic,retain) NSString *filePath;
  40. @property (nonatomic,retain) PDFListView *pdfView;
  41. @property (nonatomic,retain) UIActivityIndicatorView *activityIndicatorView;
  42. @property (nonatomic,retain) PDFToolbar *annotationToolbar;
  43. @property (nonatomic,retain) PDFBottomToolbar *bottomToolbar;
  44. @property (nonatomic,retain) PDFFreehandView *freehandView;
  45. @property (nonatomic,retain) PDFSlider *pageSlider;
  46. @property (nonatomic,retain) PDFSearchViewController *searchViewController;
  47. @property (nonatomic,retain) PDFBOTAViewController *botaViewController;
  48. @property (nonatomic,retain) UILabel *pageNumIndicator;
  49. @property (nonatomic,retain) UILabel *informationIndicator;
  50. @property (nonatomic,retain) UIButton *pageBackButton;
  51. @property (nonatomic,assign) NSInteger lastPageIndex;
  52. @property (nonatomic,assign) BOOL isCreateFromToolbar;
  53. @property (nonatomic,retain) CPDFFreeTextAnnotation *annotationFreeText;
  54. // Demo property
  55. @property (nonatomic,retain) UIImage *image;
  56. @property (nonatomic,retain) PDFHeaderFooterSettingView *headerFooterSetting;
  57. @property (nonatomic,retain) PDFHeaderFooterSettingView *batesSetting;
  58. @property (nonatomic,retain) PDFAddWaterMarkViewController *addWaterMarkViewController;
  59. @end
  60. @implementation PDFViewController
  61. #pragma mark - Initializers
  62. - (instancetype)initWithFilePath:(NSString *)filePath {
  63. if (self = [super init]) {
  64. self.filePath = filePath;
  65. }
  66. return self;
  67. }
  68. - (void)dealloc {
  69. [_annotationFreeText release];
  70. [_informationIndicator release];
  71. [_pageBackButton release];
  72. [_pageSlider release];
  73. [_pageNumIndicator release];
  74. [_botaViewController release];
  75. [_searchViewController release];
  76. [_freehandView release];
  77. [_bottomToolbar release];
  78. [_annotationToolbar release];
  79. [_activityIndicatorView release];
  80. [_pdfView release];
  81. [_filePath release];
  82. // Demo property release
  83. [_image release];
  84. [_headerFooterSetting release];
  85. [_batesSetting release];
  86. [_addWaterMarkViewController release];
  87. [super dealloc];
  88. }
  89. #pragma mark - Accessors
  90. - (PDFListView *)pdfView {
  91. if (!_pdfView) {
  92. _pdfView = [[PDFListView alloc] initWithFrame:self.view.bounds];
  93. _pdfView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
  94. _pdfView.delegate = self;
  95. _pdfView.performDelegate = self;
  96. _pdfView.performDelegate = self;
  97. }
  98. return _pdfView;
  99. }
  100. - (UIActivityIndicatorView *)activityIndicatorView {
  101. if (!_activityIndicatorView) {
  102. _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  103. _activityIndicatorView.center = self.view.center;
  104. _activityIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
  105. }
  106. [_activityIndicatorView startAnimating];
  107. return _activityIndicatorView;
  108. }
  109. #pragma mark - UIViewController Methods
  110. - (void)viewDidLoad {
  111. [super viewDidLoad];
  112. // Regarding the transparent navigation bar, if you want the PDFViewer to appear below the navigation bar (safe area), set this parameter to NO
  113. self.navigationController.navigationBar.translucent = YES;
  114. self.automaticallyAdjustsScrollViewInsets = NO;
  115. // self.navigationController.navigationBar.translucent = NO;
  116. // self.navigationController.navigationBar.barTintColor = UIColor.whiteColor;
  117. // Do any additional setup after loading the view.
  118. UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  119. [backBtn setImage:[UIImage imageNamed:@"btn_back.png"] forState:UIControlStateNormal];
  120. [backBtn addTarget:self action:@selector(buttonItemClicked_Back:) forControlEvents:UIControlEventTouchUpInside];
  121. [backBtn setExclusiveTouch:YES];
  122. [backBtn sizeToFit];
  123. UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
  124. self.navigationItem.leftBarButtonItem = backItem;
  125. [backItem release];
  126. self.view.backgroundColor = [UIColor whiteColor];
  127. [self.view addSubview:self.pdfView];
  128. [self loadDocumentWithFilePath:self.filePath completion:nil];
  129. _headerFooterSetting = [[PDFHeaderFooterSettingView alloc] init];
  130. [_headerFooterSetting setText];
  131. _batesSetting = [[PDFHeaderFooterSettingView alloc] init];
  132. [_batesSetting setText];
  133. }
  134. - (void)viewWillAppear:(BOOL)animated {
  135. [super viewWillAppear:animated];
  136. [self becomeFirstResponder];
  137. }
  138. - (void)loadDocumentWithFilePath:(NSString *)filePath completion:(void (^)(BOOL result))completion {
  139. self.title = [[filePath lastPathComponent] stringByDeletingPathExtension];
  140. self.pdfView.document = nil;
  141. [self.view addSubview:self.activityIndicatorView];
  142. [self.navigationController.view setUserInteractionEnabled:NO];
  143. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  144. NSURL *url = [NSURL fileURLWithPath:self.filePath];
  145. CPDFDocument *document = [[[CPDFDocument alloc] initWithURL:url] autorelease];
  146. dispatch_async(dispatch_get_main_queue(), ^{
  147. [self.navigationController.view setUserInteractionEnabled:YES];
  148. [self.activityIndicatorView removeFromSuperview];
  149. self.activityIndicatorView = nil;
  150. if (document.error && document.error.code != CPDFDocumentPasswordError) {
  151. UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  152. [self.navigationController popViewControllerAnimated:YES];
  153. }];
  154. UIAlertController *alert = [UIAlertController alertControllerWithTitle:@""
  155. message:NSLocalizedString(@"Sorry PDF Reader Can't open this pdf file!", nil)
  156. preferredStyle:UIAlertControllerStyleAlert];
  157. [alert addAction:okAction];
  158. [self presentViewController:alert animated:YES completion:nil];
  159. if (completion) {
  160. completion(NO);
  161. }
  162. } else {
  163. self.pdfView.document = document;
  164. if (_image == nil) {
  165. CPDFPage *pdfPage = [_pdfView.document pageAtIndex:0];
  166. [pdfPage retain];
  167. CGSize imageSize = [_pdfView.document pageSizeAtIndex:0];
  168. _image = [pdfPage thumbnailOfSize:imageSize];
  169. [_image retain];
  170. [pdfPage release];
  171. }
  172. if (completion) {
  173. completion(YES);
  174. }
  175. }
  176. });
  177. });
  178. }
  179. - (void)buttonItemClicked_Back:(id)sender {
  180. if (self.pdfView.document.isModified) {
  181. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  182. }
  183. [self.navigationController popViewControllerAnimated:YES];
  184. }
  185. #pragma mark - CPDFViewDelegate
  186. - (void)PDFViewDocumentDidLoaded:(CPDFView *)pdfView {
  187. if (self.pdfView.document.isEncrypted) {
  188. UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
  189. style:UIAlertActionStyleCancel
  190. handler:nil];
  191. UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Attention", nil)
  192. message:NSLocalizedString(@"This encrypted file can not be annotated because its format is under password protection.", nil)
  193. preferredStyle:UIAlertControllerStyleAlert];
  194. [alert addAction:okAction];
  195. [self presentViewController:alert animated:YES completion:nil];
  196. } else {
  197. [self.view addSubview:self.annotationToolbar];
  198. }
  199. [self.view addSubview:self.pageSlider];
  200. UIBarButtonItem *moreItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_more.png"]
  201. style:UIBarButtonItemStylePlain
  202. target:self
  203. action:@selector(buttonItemClicked_More:)];
  204. UIBarButtonItem *settingsItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_viewer_mode00.png"]
  205. style:UIBarButtonItemStylePlain
  206. target:self
  207. action:@selector(buttonItemClicked_ViewerMode:)];
  208. UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_search2_01.png"]
  209. style:UIBarButtonItemStylePlain
  210. target:self
  211. action:@selector(buttonItemClicked_Search:)];
  212. UIBarButtonItem *botaItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_bota.png"]
  213. style:UIBarButtonItemStylePlain
  214. target:self
  215. action:@selector(buttonItemClicked_BOTA:)];
  216. UIBarButtonItem *pageEditItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_pageedit.png"]
  217. style:UIBarButtonItemStylePlain
  218. target:self
  219. action:@selector(buttonItemClicked_PageEdit:)];
  220. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  221. self.navigationItem.rightBarButtonItems = @[moreItem, settingsItem, botaItem, searchItem, pageEditItem];
  222. PDFTitleView *titleView = [[PDFTitleView alloc] initWithTitle:self.title];
  223. [titleView showInView:self.view hideAfter:3.0 complete:nil];
  224. [titleView release];
  225. self.title = nil;
  226. } else {
  227. self.navigationItem.rightBarButtonItems = @[moreItem, botaItem, searchItem, pageEditItem];
  228. [self.view addSubview:self.bottomToolbar];
  229. }
  230. [settingsItem release];
  231. [searchItem release];
  232. [botaItem release];
  233. [self PDFViewCurrentPageDidChanged:self.pdfView];
  234. }
  235. - (void)PDFViewCurrentPageDidChanged:(CPDFView *)pdfView {
  236. if (!_pageNumIndicator) {
  237. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  238. _pageNumIndicator = [[UILabel alloc] initWithFrame:CGRectMake(6, self.view.frame.size.height-84, 60, 30)];
  239. _pageNumIndicator.autoresizingMask = UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin;
  240. } else {
  241. _pageNumIndicator = [[UILabel alloc] initWithFrame:CGRectMake((self.view.frame.size.width-60)/2.0, self.view.frame.size.height-84, 60, 30)];
  242. _pageNumIndicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin;
  243. }
  244. _pageNumIndicator.textAlignment = NSTextAlignmentCenter;
  245. _pageNumIndicator.font = [UIFont boldSystemFontOfSize:14.0f];
  246. _pageNumIndicator.textColor = [UIColor whiteColor];
  247. _pageNumIndicator.backgroundColor = [UIColor blackColor];
  248. _pageNumIndicator.alpha = 0.4;
  249. _pageNumIndicator.layer.masksToBounds = YES;
  250. _pageNumIndicator.layer.cornerRadius = 8.0f;
  251. _pageNumIndicator.hidden = YES;
  252. }
  253. [self.view addSubview:self.pageNumIndicator];
  254. self.pageNumIndicator.text = [NSString stringWithFormat:@"%ld / %ld",(long)[self.pdfView currentPageIndex]+1, (long)[self.pdfView.document pageCount]];
  255. CGSize size = [self.pageNumIndicator sizeThatFits:CGSizeMake(200, self.pageNumIndicator.frame.size.height)];
  256. self.pageNumIndicator.frame = CGRectMake(self.pageNumIndicator.frame.origin.x,
  257. self.pageNumIndicator.frame.origin.y,
  258. size.width+15, self.pageNumIndicator.frame.size.height);
  259. if (!_informationIndicator) {
  260. _informationIndicator = [[UILabel alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-84, 60, 30)];
  261. _informationIndicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleTopMargin;
  262. _informationIndicator.textAlignment = NSTextAlignmentCenter;
  263. _informationIndicator.font = [UIFont boldSystemFontOfSize:14.0f];
  264. _informationIndicator.textColor = [UIColor whiteColor];
  265. _informationIndicator.backgroundColor = [UIColor blackColor];
  266. _informationIndicator.alpha = 0.4;
  267. _informationIndicator.layer.masksToBounds = YES;
  268. _informationIndicator.layer.cornerRadius = 8.0f;
  269. _informationIndicator.hidden = YES;
  270. }
  271. [self.view addSubview:self.informationIndicator];
  272. self.informationIndicator.text = [NSString stringWithFormat:@"Powered by ComPDFKit"];
  273. size = [self.informationIndicator sizeThatFits:CGSizeMake(200, self.informationIndicator.frame.size.height)];
  274. self.informationIndicator.frame = CGRectMake(self.view.frame.size.width-(size.width+15)-6,
  275. self.informationIndicator.frame.origin.y,
  276. size.width+15, self.informationIndicator.frame.size.height);
  277. [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hidePageNumIndicator) object:nil];
  278. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  279. [self showPageNumIndicator];
  280. [self performSelector:@selector(hidePageNumIndicator) withObject:nil afterDelay:0.5];
  281. } else {
  282. if (self.bottomToolbar.alpha == 0) {
  283. [self showPageNumIndicator];
  284. [self performSelector:@selector(hidePageNumIndicator) withObject:nil afterDelay:0.5];
  285. }
  286. [self.bottomToolbar reloadData];
  287. }
  288. [self.pageSlider reloadData];
  289. }
  290. - (void)PDFViewDidClickOnLink:(CPDFView *)pdfView withURL:(NSString *)url {
  291. if(url){
  292. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
  293. } else {
  294. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
  295. style:UIAlertActionStyleCancel
  296. handler:nil];
  297. UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Error", nil)
  298. message:NSLocalizedString(@"The hyperlink is invalid.", nil)
  299. preferredStyle:UIAlertControllerStyleAlert];
  300. [alert addAction:cancelAction];
  301. [self presentViewController:alert animated:YES completion:nil];
  302. }
  303. }
  304. - (void)PDFViewPerformURL:(CPDFView *)pdfView withContent:(NSString *)content {
  305. if (content) {
  306. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:content]];
  307. } else {
  308. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
  309. style:UIAlertActionStyleCancel
  310. handler:nil];
  311. UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Error", nil)
  312. message:NSLocalizedString(@"The hyperlink is invalid.", nil)
  313. preferredStyle:UIAlertControllerStyleAlert];
  314. [alert addAction:cancelAction];
  315. [self presentViewController:alert animated:YES completion:nil];
  316. }
  317. }
  318. - (void)PDFViewPerformPrint:(CPDFView *)pdfView {
  319. NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"flatten.pdf"];
  320. [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
  321. BOOL result = [self.pdfView.document writeFlattenToURL:[NSURL fileURLWithPath:filePath]];
  322. if (result) {
  323. if ([UIPrintInteractionController isPrintingAvailable]) {
  324. UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
  325. UIPrintInfo *printInfo = [UIPrintInfo printInfo];
  326. printInfo.outputType = UIPrintInfoOutputGeneral;
  327. printInfo.jobName = self.filePath;
  328. printInfo.duplex = UIPrintInfoDuplexLongEdge;
  329. controller.printInfo = printInfo;
  330. controller.showsPageRange = YES;
  331. [controller setPrintingItem:[NSURL fileURLWithPath:filePath]];
  332. [controller presentAnimated:YES completionHandler:nil];
  333. }
  334. }
  335. }
  336. - (void)PDFViewPerformReset:(CPDFView *)pdfView {
  337. UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Yes", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
  338. [self.pdfView.document resetForm];
  339. [self.pdfView setNeedsDisplayForVisiblePages];
  340. }];
  341. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"No", nil) style:UIAlertActionStyleCancel handler:nil];
  342. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
  343. message:[NSString stringWithFormat:NSLocalizedString(@"Do you really want to reset the form?", nil)]
  344. preferredStyle:UIAlertControllerStyleAlert];
  345. [alert addAction:okAction];
  346. [alert addAction:cancelAction];
  347. [self presentViewController:alert animated:YES completion:nil];
  348. }
  349. - (void)PDFViewShouldBeginEditing:(CPDFView *)pdfView textView:(UITextView *)textView forAnnotation:(CPDFFreeTextAnnotation *)annotation {
  350. self.annotationFreeText = annotation;
  351. PDFKeyboardToolbar *keyboardToolbar = [[[PDFKeyboardToolbar alloc] initWithFontName:annotation.font.fontName fontSize:annotation.font.pointSize] autorelease];
  352. keyboardToolbar.delegate = self;
  353. [keyboardToolbar refreshFontName:annotation.font.fontName fontSize:annotation.font.pointSize opacity:annotation.opacity];
  354. [keyboardToolbar bindToTextView:textView];
  355. }
  356. - (void)PDFViewShouldEndEditing:(CPDFView *)pdfView textView:(UITextView *)textView forAnnotation:(CPDFFreeTextAnnotation *)annotation {
  357. }
  358. /*
  359. 1 - PDFViewer will call back this method when the user zooms or drags the PDFViewer to stop.
  360. 2 - [self.pdfView goToDestination:<#(CPDFDestination *)#> animated:<#(BOOL)#>];
  361. */
  362. - (void)PDFViewDidEndDragging:(CPDFView *)pdfView {
  363. // CPDFDestination *currentDestination = self.pdfView.currentDestination;
  364. }
  365. #pragma mark - PDFListViewDelegate
  366. - (void)PDFViewPerformOpenNote:(PDFListView *)pdfView forAnnotation:(CPDFAnnotation *)annotation {
  367. CGRect rect = [pdfView convertRect:annotation.bounds fromPage:annotation.page];
  368. PDFNoteViewController *vc = [[PDFNoteViewController alloc] init];
  369. [vc setContent:annotation.contents];
  370. vc.callback = ^(NSString *string, BOOL isDelete) {
  371. if (isDelete) {
  372. [annotation.page removeAnnotation:annotation];
  373. [self.pdfView setNeedsDisplayForPage:annotation.page];
  374. } else {
  375. annotation.contents = string;
  376. }
  377. };
  378. [vc showViewController:self inRect:rect];
  379. [vc release];
  380. }
  381. - (void)PDFViewPerformChangeColor:(PDFListView *)pdfView forAnnotation:(CPDFAnnotation *)annotation {
  382. CGRect rect = [pdfView convertRect:annotation.bounds fromPage:annotation.page];
  383. if ([annotation isKindOfClass:[CPDFCircleAnnotation class]] ||
  384. [annotation isKindOfClass:[CPDFSquareAnnotation class]]) {
  385. __block PDFShapeViewController *vc = [[PDFShapeViewController alloc] init];
  386. vc.color = annotation.color;
  387. vc.opacity = annotation.opacity*100;
  388. vc.fillColor = [(CPDFCircleAnnotation *)annotation interiorColor];
  389. if ([(CPDFCircleAnnotation *)annotation interiorOpacity] > 0) {
  390. vc.fillOpacity = [(CPDFCircleAnnotation *)annotation interiorOpacity]*100;
  391. } else {
  392. vc.fillOpacity = 0;
  393. }
  394. vc.borderWidth = annotation.borderWidth;
  395. vc.callback = ^{
  396. annotation.color = vc.color;
  397. annotation.opacity = vc.opacity/100;
  398. [(CPDFCircleAnnotation *)annotation setInteriorColor:vc.fillColor];
  399. [(CPDFCircleAnnotation *)annotation setInteriorOpacity:vc.fillOpacity/100];
  400. annotation.borderWidth = vc.borderWidth;
  401. [self.pdfView setNeedsDisplayForPage:annotation.page];
  402. };
  403. [vc showViewController:self inRect:rect];
  404. [vc release];
  405. } else {
  406. __block PDFColorViewController *vc = [[PDFColorViewController alloc] init];
  407. vc.color = annotation.color;
  408. vc.opacity = annotation.opacity*100;
  409. vc.callback = ^{
  410. annotation.color = vc.color;
  411. annotation.opacity = vc.opacity/100;
  412. [self.pdfView setNeedsDisplayForPage:annotation.page];
  413. };
  414. [vc showViewController:self inRect:rect];
  415. [vc release];
  416. }
  417. }
  418. - (void)PDFViewPerformShare:(PDFListView *)pdfView forAnnotation:(CPDFMarkupAnnotation *)annotation {
  419. CGRect rect = [pdfView convertRect:annotation.bounds fromPage:annotation.page];
  420. NSString *text = [annotation markupText] ? : @"";
  421. UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:@[text] applicationActivities:nil];
  422. vc.popoverPresentationController.sourceView = self.view;
  423. vc.popoverPresentationController.sourceRect = rect;
  424. [self presentViewController:vc animated:YES completion:nil];
  425. [vc release];
  426. }
  427. - (void)PDFViewPerformSave:(PDFListView *)pdfView forAnnotation:(CPDFStampAnnotation *)annotation {
  428. if ([annotation stampImage]) {
  429. UIImageWriteToSavedPhotosAlbum([annotation stampImage], self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
  430. }
  431. }
  432. - (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
  433. if (!error) {
  434. dispatch_async(dispatch_get_main_queue(), ^{
  435. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
  436. message:NSLocalizedString(@"This image has been saved to the photo library.", nil)
  437. preferredStyle:UIAlertControllerStyleAlert];
  438. [self presentViewController:alert animated:YES completion:nil];
  439. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  440. [alert dismissViewControllerAnimated:YES completion:nil];
  441. });
  442. });
  443. }
  444. }
  445. - (void)PDFViewPerformPopup:(PDFListView *)pdfView forAnnotation:(CPDFMarkupAnnotation *)annotation {
  446. CGRect rect = [pdfView convertRect:annotation.bounds fromPage:annotation.page];
  447. PDFNoteViewController *vc = [[PDFNoteViewController alloc] init];
  448. [vc setContent:annotation.contents];
  449. vc.callback = ^(NSString *string, BOOL isDelete) {
  450. if (isDelete) {
  451. annotation.contents = @"";
  452. [annotation removePopup];
  453. [self.pdfView setNeedsDisplayForPage:annotation.page];
  454. } else {
  455. annotation.contents = string;
  456. }
  457. };
  458. [vc showViewController:self inRect:rect];
  459. [vc release];
  460. }
  461. - (void)PDFViewPerformEditLink:(PDFListView *)pdfView forAnnotation:(CPDFLinkAnnotation *)annotation {
  462. PDFLinkViewController *vc = [[PDFLinkViewController alloc] init];
  463. NSString *url = annotation.URL;
  464. CPDFDestination *destination = annotation.destination;
  465. if (url) {
  466. if ([url hasPrefix:@"mailto:"]) {
  467. vc.type = 2;
  468. vc.content = [url substringFromIndex:7];
  469. } else {
  470. vc.type = 0;
  471. vc.content = url;
  472. }
  473. } else if (destination) {
  474. vc.type = 1;
  475. vc.content = [NSString stringWithFormat:@"%@", @(destination.pageIndex+1)];
  476. }
  477. vc.callback = ^(NSString *content, NSInteger type) {
  478. if (content) {
  479. if (type == 0) {
  480. annotation.URL = content;
  481. } else if (type == 1) {
  482. annotation.destination = [[[CPDFDestination alloc] initWithDocument:pdfView.document
  483. pageIndex:[content integerValue]-1
  484. atPoint:CGPointZero
  485. zoom:1] autorelease];
  486. } else if (type == 2) {
  487. annotation.URL = [NSString stringWithFormat:@"mailto:%@", content];
  488. }
  489. } else {
  490. pdfView.activeAnnotation = nil;
  491. [pdfView setNeedsDisplayForPage:annotation.page];
  492. }
  493. };
  494. vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
  495. [self presentViewController:vc animated:YES completion:nil];
  496. [vc release];
  497. }
  498. - (void)PDFViewPerformSignatureWidget:(PDFListView *)pdfView forAnnotation:(CPDFSignatureWidgetAnnotation *)annotation {
  499. PDFSignatureViewController *vc = [[PDFSignatureViewController alloc] init];
  500. vc.callback = ^(UIImage *image) {
  501. [annotation signWithImage:image];
  502. [pdfView setNeedsDisplayForPage:annotation.page];
  503. };
  504. UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
  505. nav.modalPresentationStyle = UIModalPresentationFormSheet;
  506. [self presentViewController:nav animated:YES completion:nil];
  507. [nav release];
  508. [vc release];
  509. }
  510. - (void)PDFViewPerformShare:(PDFListView *)pdfView forSelection:(CPDFSelection *)selection {
  511. CGRect rect = [pdfView convertRect:selection.bounds fromPage:selection.page];
  512. NSString *text = [selection string] ? : @"";
  513. UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:@[text] applicationActivities:nil];
  514. vc.popoverPresentationController.sourceView = self.view;
  515. vc.popoverPresentationController.sourceRect = rect;
  516. [self presentViewController:vc animated:YES completion:nil];
  517. [vc release];
  518. }
  519. - (void)PDFViewPerformDefine:(PDFListView *)pdfView forSelection:(CPDFSelection *)selection {
  520. NSString *word = selection.string;
  521. word = [word stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
  522. word = [word stringByTrimmingCharactersInSet:[NSCharacterSet controlCharacterSet]];
  523. word = [word stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
  524. CGRect rect = [self.pdfView convertRect:selection.bounds fromPage:selection.page];
  525. UIReferenceLibraryViewController *reference = [[[UIReferenceLibraryViewController alloc] initWithTerm:word] autorelease];
  526. reference.modalPresentationStyle = UIModalPresentationPopover;
  527. UIPopoverPresentationController *popVC = reference.popoverPresentationController;
  528. popVC.delegate = self;
  529. popVC.sourceRect = rect;
  530. popVC.sourceView = self.pdfView;
  531. [self presentViewController:reference animated:YES completion:nil];
  532. }
  533. - (void)PDFViewPerformGoogleSearch:(PDFListView *)pdfView forSelection:(CPDFSelection *)selection {
  534. NSString *string = [[NSString stringWithFormat:@"http://www.google.com/search?q=%@&hl=en", selection.string] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
  535. NSURL *url = [NSURL URLWithString:string];
  536. [[UIApplication sharedApplication] openURL:url];
  537. }
  538. - (void)PDFViewPerformWikiSearch:(PDFListView *)pdfView forSelection:(CPDFSelection *)selection {
  539. NSString *string = [[NSString stringWithFormat:@"http://en.wikipedia.org/wiki/%@", selection.string] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
  540. NSURL *url = [NSURL URLWithString:string];
  541. [[UIApplication sharedApplication] openURL:url];
  542. }
  543. - (void)PDFViewPerformAddSignture:(PDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page {
  544. PDFSignatureViewController *vc = [[PDFSignatureViewController alloc] init];
  545. vc.callback = ^(UIImage *image) {
  546. CPDFSignatureAnnotation *annotation = [[[CPDFSignatureAnnotation alloc] initWithDocument:pdfView.document] autorelease];
  547. [annotation setImage:image];
  548. CGRect bounds = annotation.bounds;
  549. bounds.origin.x = point.x-bounds.size.width/2.0;
  550. bounds.origin.y = point.y-bounds.size.height/2.0;
  551. annotation.bounds = bounds;
  552. [self.pdfView addAnnotation:annotation forPage:page];
  553. };
  554. UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
  555. nav.modalPresentationStyle = UIModalPresentationFormSheet;
  556. [self presentViewController:nav animated:YES completion:nil];
  557. [nav release];
  558. [vc release];
  559. }
  560. - (void)PDFViewPerformAddStamp:(PDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page {
  561. CGPoint p = [self.pdfView convertPoint:point fromPage:page];
  562. CGRect rect = CGRectMake(p.x, p.y, 2, 2);
  563. PDFStampViewController *vc = [[PDFStampViewController alloc] init];
  564. vc.callback = ^(NSInteger selectedIndex, NSDictionary *stamp) {
  565. if (selectedIndex != -1) {
  566. if (stamp) {
  567. if (stamp[PDFAnnotationStampKeyImagePath]) {
  568. UIImage *image = [UIImage imageWithContentsOfFile:stamp[PDFAnnotationStampKeyImagePath]];
  569. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:pdfView.document image:image] autorelease];
  570. CGRect bounds = annotation.bounds;
  571. bounds.origin.x = point.x-bounds.size.width/2.0;
  572. bounds.origin.y = point.y-bounds.size.height/2.0;
  573. annotation.bounds = bounds;
  574. [self.pdfView addAnnotation:annotation forPage:page];
  575. } else {
  576. NSString *stampText = stamp[PDFAnnotationStampKeyText];
  577. BOOL stampShowDate = [stamp[PDFAnnotationStampKeyShowDate] boolValue];
  578. BOOL stampShowTime = [stamp[PDFAnnotationStampKeyShowTime] boolValue];
  579. CPDFStampStyle stampStyle = [stamp[PDFAnnotationStampKeyStyle] integerValue];
  580. CPDFStampShape stampShape = [stamp[PDFAnnotationStampKeyShape] integerValue];
  581. NSString *detailText = nil;
  582. NSTimeZone *timename = [NSTimeZone systemTimeZone];
  583. NSDateFormatter *outputFormatter = [[[NSDateFormatter alloc] init] autorelease];
  584. [outputFormatter setTimeZone:timename];
  585. if (stampShowDate && !stampShowTime){
  586. detailText = [NSDateFormatter localizedStringFromDate:[NSDate date]
  587. dateStyle:NSDateFormatterShortStyle
  588. timeStyle:NSDateFormatterNoStyle];
  589. } else if (stampShowTime && !stampShowDate) {
  590. [outputFormatter setDateFormat:@"HH:mm:ss"];
  591. detailText = [outputFormatter stringFromDate:[NSDate date]];
  592. } else if (stampShowDate && stampShowTime) {
  593. [outputFormatter setDateFormat:@" HH:mm"];
  594. detailText = [NSDateFormatter localizedStringFromDate:[NSDate date]
  595. dateStyle:NSDateFormatterShortStyle
  596. timeStyle:NSDateFormatterNoStyle];
  597. detailText = [detailText stringByAppendingString:[outputFormatter stringFromDate:[NSDate date]]];
  598. }
  599. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:pdfView.document text:stampText detailText:detailText style:stampStyle shape:stampShape] autorelease];
  600. CGRect bounds = annotation.bounds;
  601. bounds.origin.x = point.x-bounds.size.width/2.0;
  602. bounds.origin.y = point.y-bounds.size.height/2.0;
  603. annotation.bounds = bounds;
  604. [self.pdfView addAnnotation:annotation forPage:page];
  605. }
  606. } else {
  607. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:pdfView.document type:selectedIndex+1] autorelease];
  608. CGRect bounds = annotation.bounds;
  609. bounds.origin.x = point.x-bounds.size.width/2.0;
  610. bounds.origin.y = point.y-bounds.size.height/2.0;
  611. annotation.bounds = bounds;
  612. [self.pdfView addAnnotation:annotation forPage:page];
  613. }
  614. }
  615. };
  616. [vc showViewController:self inRect:rect];
  617. [vc release];
  618. }
  619. - (void)PDFViewPerformAddImage:(PDFListView *)pdfView atPoint:(CGPoint)point forPage:(CPDFPage *)page {
  620. self.isCreateFromToolbar = NO;
  621. CGPoint p = [self.pdfView convertPoint:point fromPage:page];
  622. CGRect rect = CGRectMake(p.x, p.y, 2, 2);
  623. UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Use Camera", nil)
  624. style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  625. UIImagePickerController *imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
  626. imagePickerController.delegate = self;
  627. imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
  628. [self presentViewController:imagePickerController animated:YES completion:nil];
  629. }];
  630. UIAlertAction *photoAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Photo Library", nil)
  631. style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  632. UIImagePickerController *imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
  633. imagePickerController.delegate = self;
  634. imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  635. imagePickerController.modalPresentationStyle = UIModalPresentationPopover;
  636. UIPopoverPresentationController *popVC = imagePickerController.popoverPresentationController;
  637. popVC.delegate = self;
  638. popVC.sourceRect = rect;
  639. popVC.sourceView = self.view;
  640. [self presentViewController:imagePickerController animated:YES completion:nil];
  641. }];
  642. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
  643. style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  644. self.pdfView.annotationMode = PDFViewAnnotationModeNone;
  645. [self.annotationToolbar reloadData];
  646. }];
  647. UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil
  648. message:nil
  649. preferredStyle:UIAlertControllerStyleActionSheet];
  650. [actionSheet addAction:cameraAction];
  651. [actionSheet addAction:photoAction];
  652. [actionSheet addAction:cancelAction];
  653. actionSheet.modalPresentationStyle = UIModalPresentationPopover;
  654. UIPopoverPresentationController *popVC = actionSheet.popoverPresentationController;
  655. popVC.delegate = self;
  656. popVC.sourceRect = rect;
  657. popVC.sourceView = self.view;
  658. [self presentViewController:actionSheet animated:YES completion:nil];
  659. }
  660. - (void)PDFViewPerformTouchEnded:(PDFListView *)pdfView {
  661. if (PDFViewAnnotationModeNone != self.pdfView.annotationMode) {
  662. self.pdfView.annotationMode = PDFViewAnnotationModeNone;
  663. [self.annotationToolbar reloadData];
  664. return;
  665. }
  666. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  667. if (self.navigationController.navigationBarHidden) {
  668. [self.navigationController setNavigationBarHidden:NO animated:YES];
  669. [UIView animateWithDuration:0.3 animations:^{
  670. CGRect frame = self.annotationToolbar.frame;
  671. frame.origin.y = self.view.bounds.size.height-frame.size.height;
  672. self.annotationToolbar.frame = frame;
  673. self.pageSlider.alpha = 1.0;
  674. }];
  675. } else {
  676. [self.navigationController setNavigationBarHidden:YES animated:YES];
  677. [UIView animateWithDuration:0.3 animations:^{
  678. CGRect frame = self.annotationToolbar.frame;
  679. frame.origin.y = self.view.bounds.size.height;
  680. self.annotationToolbar.frame = frame;
  681. self.pageSlider.alpha = 0.0;
  682. }];
  683. }
  684. } else {
  685. if (self.navigationController.navigationBarHidden) {
  686. [self.navigationController setNavigationBarHidden:NO animated:YES];
  687. [UIView animateWithDuration:0.3 animations:^{
  688. self.annotationToolbar.alpha = 1.0;
  689. self.pageSlider.alpha = 1.0;
  690. self.bottomToolbar.alpha = 1.0;
  691. }];
  692. } else {
  693. [self.navigationController setNavigationBarHidden:YES animated:YES];
  694. [UIView animateWithDuration:0.3 animations:^{
  695. self.annotationToolbar.alpha = 0.0;
  696. self.pageSlider.alpha = 0.0;
  697. self.bottomToolbar.alpha = 0.0;
  698. }];
  699. }
  700. }
  701. }
  702. - (void)PDFViewPerformWillGoTo:(PDFListView *)pdfView pageIndex:(NSInteger)pageIndex {
  703. self.lastPageIndex = self.pdfView.currentPageIndex;
  704. [self.view addSubview:self.pageBackButton];
  705. }
  706. #pragma mark - PDFKeyboardDelegate
  707. - (void)keyboard:(PDFKeyboardToolbar *)toolbar updateFontName:(NSString *)fontName {
  708. UIFont *font = [UIFont fontWithName:fontName size:self.annotationFreeText.font.pointSize];
  709. [self.pdfView setEditAnnotationFreeTextFont:font];
  710. }
  711. - (void)keyboard:(PDFKeyboardToolbar *)toolbar updateFontSize:(CGFloat)fontSize {
  712. UIFont *font = [UIFont fontWithName:self.annotationFreeText.font.fontName size:fontSize];
  713. [self.pdfView setEditAnnotationFreeTextFont:font];
  714. }
  715. - (void)keyboard:(PDFKeyboardToolbar *)toolbar updateTextColor:(UIColor *)textColor {
  716. UIColor *color = [textColor colorWithAlphaComponent:self.annotationFreeText.opacity];
  717. [self.pdfView setEditAnnotationFreeTextColor:color];
  718. }
  719. - (void)keyboardShouldDissmiss:(PDFKeyboardToolbar *)toolbar {
  720. [self.pdfView commitEditAnnotationFreeText];
  721. self.pdfView.annotationMode = PDFViewAnnotationModeNone;
  722. [self.annotationToolbar reloadData];
  723. }
  724. - (void)keyboard:(PDFKeyboardToolbar *)toolbar updateOpacity:(CGFloat)opacity {
  725. UIColor *color = [self.annotationFreeText.fontColor colorWithAlphaComponent:opacity];
  726. [self.pdfView setEditAnnotationFreeTextColor:color];
  727. }
  728. #pragma mark - init Bottom Toolbar, Only iPad
  729. - (PDFBottomToolbar *)bottomToolbar {
  730. if (!_bottomToolbar) {
  731. _bottomToolbar = [[PDFBottomToolbar alloc] initWithFrame:CGRectMake((self.view.bounds.size.width-300)/2.0, self.view.bounds.size.height-40, 300, 40)];
  732. _bottomToolbar.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin;
  733. _bottomToolbar.pdfViewController = self;
  734. }
  735. return _bottomToolbar;
  736. }
  737. #pragma mark - init Annotation Toolbar
  738. - (PDFToolbar *)annotationToolbar {
  739. if (!_annotationToolbar) {
  740. __block __typeof(self) blockSelf = self;
  741. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  742. BOOL iPhoneX = [UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO;
  743. CGFloat height = iPhoneX ? 78 : 44;
  744. _annotationToolbar = [[PDFToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height-height,
  745. self.view.bounds.size.width, height)];
  746. _annotationToolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
  747. } else {
  748. CGFloat height = 600;
  749. _annotationToolbar = [[PDFToolbar alloc] initWithFrame:CGRectMake(0, (self.view.bounds.size.height-height)/2.0, 44, height)];
  750. _annotationToolbar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
  751. }
  752. _annotationToolbar.callback = ^(NSInteger index, BOOL isSelected, UIButton *button) {
  753. if (isSelected) {
  754. NSString *promptString = nil;
  755. if (index == PDFToolbarNote) {
  756. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeNote;
  757. } else if (index == PDFToolbarHighlight) {
  758. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeHighlight;
  759. static BOOL showHighlightPromptString = YES;
  760. if (showHighlightPromptString) {
  761. showHighlightPromptString = NO;
  762. promptString = NSLocalizedString(@"Drag over the text to highlight", nil);
  763. }
  764. } else if (index == PDFToolbarUnderline) {
  765. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeUnderline;
  766. static BOOL showUnderlinePromptString = YES;
  767. if (showUnderlinePromptString) {
  768. showUnderlinePromptString = NO;
  769. promptString = NSLocalizedString(@"Drag over the text to underline", nil);
  770. }
  771. } else if (index == PDFToolbarStrikeout) {
  772. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeStrikeout;
  773. static BOOL showStrikeoutPromptString = YES;
  774. if (showStrikeoutPromptString) {
  775. showStrikeoutPromptString = NO;
  776. promptString = NSLocalizedString(@"Drag over the text to strikethrough", nil);
  777. }
  778. } else if (index == PDFToolbarSquiggly) {
  779. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeSquiggly;
  780. static BOOL showSquigglyPromptString = YES;
  781. if (showSquigglyPromptString) {
  782. showSquigglyPromptString = NO;
  783. promptString = NSLocalizedString(@"Drag over the text to Wavy line", nil);
  784. }
  785. } else if (index == PDFToolbarFreehand) {
  786. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeInk;
  787. [blockSelf.pdfView beginDrawing];
  788. [blockSelf showFreehandView];
  789. } else if (index == PDFToolbarShape) {
  790. if (blockSelf.annotationToolbar.shapeStyle == 0) {
  791. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeCircle;
  792. } else if (blockSelf.annotationToolbar.shapeStyle == 1) {
  793. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeSquare;
  794. } else if (blockSelf.annotationToolbar.shapeStyle == 2) {
  795. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeArrow;
  796. } else {
  797. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeLine;
  798. }
  799. } else if (index == PDFToolbarFreeText) {
  800. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeFreeText;
  801. } else if (index == PDFToolbarSignature) {
  802. [blockSelf showSignatureViewController];
  803. } else if (index == PDFToolbarStamp) {
  804. CGRect rect = [button.superview convertRect:button.frame toView:blockSelf.view];
  805. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeStamp;
  806. [blockSelf showStampViewControllerInRect:rect];
  807. } else if (index == PDFToolbarImage) {
  808. CGRect rect = [button.superview convertRect:button.frame toView:blockSelf.view];
  809. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeImage;
  810. [blockSelf showImagePickerControllerInRect:rect];
  811. } else if (index == PDFToolbarLink) {
  812. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeLink;
  813. static BOOL showLinkPromptString = YES;
  814. if (showLinkPromptString) {
  815. showLinkPromptString = NO;
  816. promptString = NSLocalizedString(@"Drag to specify an area where you would like to add a hyperlink to this PDF", nil);
  817. }
  818. }
  819. if (promptString) {
  820. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:promptString preferredStyle:UIAlertControllerStyleAlert];
  821. [blockSelf presentViewController:alert animated:YES completion:nil];
  822. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  823. [alert dismissViewControllerAnimated:YES completion:nil];
  824. });
  825. }
  826. } else {
  827. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeNone;
  828. }
  829. };
  830. }
  831. return _annotationToolbar;
  832. }
  833. #pragma mark - init Back Button
  834. - (UIButton *)pageBackButton {
  835. if (!_pageBackButton) {
  836. _pageBackButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
  837. _pageBackButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
  838. [_pageBackButton addTarget:self action:@selector(buttonItemClicked_PageBack:) forControlEvents:UIControlEventTouchUpInside];
  839. [_pageBackButton setImage:[UIImage imageNamed:@"btn_pageback.png"] forState:UIControlStateNormal];
  840. [_pageBackButton sizeToFit];
  841. CGRect frame = _pageBackButton.frame;
  842. frame.origin.x = self.view.frame.size.width-_pageBackButton.frame.size.width-40;
  843. frame.origin.y = self.view.frame.size.height-_pageBackButton.frame.size.height-60;
  844. _pageBackButton.frame = frame;
  845. }
  846. return _pageBackButton;
  847. }
  848. - (void)buttonItemClicked_PageBack:(id)sender {
  849. [self.pdfView goToPageIndex:self.lastPageIndex animated:NO];
  850. [self.pageBackButton removeFromSuperview];
  851. }
  852. #pragma mark - init Slider
  853. - (PDFSlider *)pageSlider {
  854. if (!_pageSlider) {
  855. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  856. _pageSlider = [[PDFSlider alloc] initWithFrame:CGRectMake(self.view.bounds.size.width-22, 64, 22, self.view.bounds.size.height-self.annotationToolbar.bounds.size.height-64)];
  857. } else {
  858. _pageSlider = [[PDFSlider alloc] initWithFrame:CGRectMake(self.view.bounds.size.width-22, 64, 22, self.view.bounds.size.height-64)];
  859. }
  860. _pageSlider.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin;
  861. _pageSlider.pdfViewController = self;
  862. }
  863. return _pageSlider;
  864. }
  865. #pragma mark - Annotation - Image : ImagePickerController
  866. - (void)showImagePickerControllerInRect:(CGRect)rect {
  867. self.isCreateFromToolbar = YES;
  868. UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Use Camera", nil)
  869. style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  870. UIImagePickerController *imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
  871. imagePickerController.delegate = self;
  872. imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
  873. [self presentViewController:imagePickerController animated:YES completion:nil];
  874. }];
  875. UIAlertAction *photoAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Photo Library", nil)
  876. style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  877. UIImagePickerController *imagePickerController = [[[UIImagePickerController alloc] init] autorelease];
  878. imagePickerController.delegate = self;
  879. imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  880. imagePickerController.modalPresentationStyle = UIModalPresentationPopover;
  881. UIPopoverPresentationController *popVC = imagePickerController.popoverPresentationController;
  882. popVC.delegate = self;
  883. popVC.sourceRect = rect;
  884. popVC.sourceView = self.view;
  885. [self presentViewController:imagePickerController animated:YES completion:nil];
  886. }];
  887. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
  888. style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  889. self.pdfView.annotationMode = PDFViewAnnotationModeNone;
  890. [self.annotationToolbar reloadData];
  891. }];
  892. UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil
  893. message:nil
  894. preferredStyle:UIAlertControllerStyleActionSheet];
  895. [actionSheet addAction:cameraAction];
  896. [actionSheet addAction:photoAction];
  897. [actionSheet addAction:cancelAction];
  898. actionSheet.modalPresentationStyle = UIModalPresentationPopover;
  899. UIPopoverPresentationController *popVC = actionSheet.popoverPresentationController;
  900. popVC.delegate = self;
  901. popVC.sourceRect = rect;
  902. popVC.sourceView = self.view;
  903. [self presentViewController:actionSheet animated:YES completion:nil];
  904. }
  905. #pragma mark - Annotation - Stamp : Standard & Custom StampViewController
  906. - (void)showStampViewControllerInRect:(CGRect)rect {
  907. PDFStampViewController *vc = [[PDFStampViewController alloc] init];
  908. vc.callback = ^(NSInteger selectedIndex, NSDictionary *stamp) {
  909. if (selectedIndex == -1) {
  910. self.pdfView.annotationMode = PDFViewAnnotationModeNone;
  911. [self.annotationToolbar reloadData];
  912. } else {
  913. if (stamp) {
  914. if (stamp[PDFAnnotationStampKeyImagePath]) {
  915. UIImage *image = [UIImage imageWithContentsOfFile:stamp[PDFAnnotationStampKeyImagePath]];
  916. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:self.pdfView.document image:image] autorelease];
  917. self.pdfView.addAnnotation = annotation;
  918. } else {
  919. NSString *stampText = stamp[PDFAnnotationStampKeyText];
  920. BOOL stampShowDate = [stamp[PDFAnnotationStampKeyShowDate] boolValue];
  921. BOOL stampShowTime = [stamp[PDFAnnotationStampKeyShowTime] boolValue];
  922. CPDFStampStyle stampStyle = [stamp[PDFAnnotationStampKeyStyle] integerValue];
  923. CPDFStampShape stampShape = [stamp[PDFAnnotationStampKeyShape] integerValue];
  924. NSString *detailText = nil;
  925. NSTimeZone *timename = [NSTimeZone systemTimeZone];
  926. NSDateFormatter *outputFormatter = [[[NSDateFormatter alloc] init] autorelease];
  927. [outputFormatter setTimeZone:timename];
  928. if (stampShowDate && !stampShowTime){
  929. detailText = [NSDateFormatter localizedStringFromDate:[NSDate date]
  930. dateStyle:NSDateFormatterShortStyle
  931. timeStyle:NSDateFormatterNoStyle];
  932. } else if (stampShowTime && !stampShowDate) {
  933. [outputFormatter setDateFormat:@"HH:mm:ss"];
  934. detailText = [outputFormatter stringFromDate:[NSDate date]];
  935. } else if (stampShowDate && stampShowTime) {
  936. [outputFormatter setDateFormat:@" HH:mm"];
  937. detailText = [NSDateFormatter localizedStringFromDate:[NSDate date]
  938. dateStyle:NSDateFormatterShortStyle
  939. timeStyle:NSDateFormatterNoStyle];
  940. detailText = [detailText stringByAppendingString:[outputFormatter stringFromDate:[NSDate date]]];
  941. }
  942. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:self.pdfView.document text:stampText detailText:detailText style:stampStyle shape:stampShape] autorelease];
  943. self.pdfView.addAnnotation = annotation;
  944. }
  945. } else {
  946. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:self.pdfView.document type:selectedIndex+1] autorelease];
  947. self.pdfView.addAnnotation = annotation;
  948. }
  949. }
  950. };
  951. [vc showViewController:self inRect:rect];
  952. [vc release];
  953. }
  954. #pragma mark - Annotation - Freehand : Show & Remove FreehandView
  955. - (void)showFreehandView {
  956. if (!_freehandView) {
  957. __block __typeof(self) blockSelf = self;
  958. _freehandView = [[PDFFreehandView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width-310, 30, 300, 60)];
  959. _freehandView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
  960. _freehandView.callback = ^(NSInteger buttonTag, BOOL isSelected) {
  961. if (buttonTag == 0) {
  962. // Undo Button
  963. [blockSelf.pdfView drawUndo];
  964. } else if (buttonTag == 1) {
  965. // Redo Button
  966. [blockSelf.pdfView drawRedo];
  967. } else if (buttonTag == 2) {
  968. // Erase Button
  969. [blockSelf.pdfView setDrawErasing:isSelected];
  970. } else if (buttonTag == 3) {
  971. // Color Button
  972. [blockSelf.pdfView commitDrawing];
  973. } else if (buttonTag == 4) {
  974. // Clear Button
  975. [blockSelf removeFreehandView];
  976. [blockSelf.annotationToolbar reloadData];
  977. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeNone;
  978. } else if (buttonTag == 5) {
  979. // Save Button
  980. [blockSelf.pdfView commitDrawing];
  981. [blockSelf removeFreehandView];
  982. [blockSelf.annotationToolbar reloadData];
  983. blockSelf.pdfView.annotationMode = PDFViewAnnotationModeNone;
  984. }
  985. };
  986. }
  987. [self.view addSubview:_freehandView];
  988. [self.navigationController setNavigationBarHidden:YES animated:YES];
  989. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  990. [UIView animateWithDuration:0.3 animations:^{
  991. CGRect frame = self.annotationToolbar.frame;
  992. frame.origin.y = self.view.bounds.size.height;
  993. self.annotationToolbar.frame = frame;
  994. // self.pageSlider.alpha = 0.0;
  995. }];
  996. } else {
  997. [UIView animateWithDuration:0.3 animations:^{
  998. self.annotationToolbar.alpha = 0.0;
  999. // self.pageSlider.alpha = 0.0;
  1000. self.bottomToolbar.alpha = 0.0;
  1001. }];
  1002. }
  1003. }
  1004. - (void)removeFreehandView {
  1005. [self.freehandView removeFromSuperview];
  1006. self.freehandView = nil;
  1007. [self.navigationController setNavigationBarHidden:NO animated:YES];
  1008. if (UIUserInterfaceIdiomPhone == UI_USER_INTERFACE_IDIOM()) {
  1009. [UIView animateWithDuration:0.3 animations:^{
  1010. CGRect frame = self.annotationToolbar.frame;
  1011. frame.origin.y = self.view.bounds.size.height-frame.size.height;
  1012. self.annotationToolbar.frame = frame;
  1013. self.pageSlider.alpha = 1.0;
  1014. }];
  1015. } else {
  1016. [UIView animateWithDuration:0.3 animations:^{
  1017. self.annotationToolbar.alpha = 1.0;
  1018. self.pageSlider.alpha = 1.0;
  1019. self.bottomToolbar.alpha = 1.0;
  1020. }];
  1021. }
  1022. }
  1023. #pragma mark - Annotation - Signature : SignatureViewController
  1024. - (void)showSignatureViewController {
  1025. PDFSignatureViewController *vc = [[PDFSignatureViewController alloc] init];
  1026. vc.callback = ^(UIImage *image) {
  1027. if (image) {
  1028. CPDFSignatureAnnotation *annotation = [[[CPDFSignatureAnnotation alloc] initWithDocument:self.pdfView.document] autorelease];
  1029. [annotation setImage:image];
  1030. [self.pdfView addAnnotation:annotation];
  1031. }
  1032. [self.annotationToolbar reloadData];
  1033. };
  1034. UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
  1035. nav.modalPresentationStyle = UIModalPresentationFormSheet;
  1036. [self presentViewController:nav animated:YES completion:nil];
  1037. [nav release];
  1038. [vc release];
  1039. }
  1040. #pragma mark - Viewer Mode : Themes, Brightness, Scroll Pages, Crop Mode, Night Mode
  1041. - (void)buttonItemClicked_ViewerMode:(UIBarButtonItem *)barButtonItem {
  1042. __block PDFViewerModeViewController *vc = [[PDFViewerModeViewController alloc] init];
  1043. vc.themesType = self.pdfView.displayMode;
  1044. vc.color = self.pdfView.displayModeCustomColor;
  1045. vc.brightness = [UIScreen mainScreen].brightness;
  1046. vc.scrollType = self.pdfView.displayDirection;
  1047. vc.isCropMode = self.pdfView.displayCrop;
  1048. vc.callback = ^(NSInteger index) {
  1049. if (index == 0) {
  1050. self.pdfView.displayModeCustomColor = vc.color;
  1051. self.pdfView.displayMode = vc.themesType;
  1052. [self.pdfView layoutDocumentView];
  1053. } else if (index == 1) {
  1054. [UIScreen mainScreen].brightness = vc.brightness;
  1055. } else if (index == 2) {
  1056. self.pdfView.displayDirection = vc.scrollType;
  1057. [self.pdfView layoutDocumentView];
  1058. } else if (index == 3) {
  1059. self.view.window.userInteractionEnabled = NO;
  1060. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  1061. self.pdfView.displayCrop = vc.isCropMode;
  1062. dispatch_async(dispatch_get_main_queue(), ^{
  1063. self.view.window.userInteractionEnabled = YES;
  1064. [self.pdfView layoutDocumentView];
  1065. });
  1066. });
  1067. }
  1068. };
  1069. [vc showViewController:self inBarButtonItem:barButtonItem];
  1070. [vc release];
  1071. }
  1072. #pragma mark - PDFViewer - Search Text & Jump Page
  1073. - (void)buttonItemClicked_Search:(UIBarButtonItem *)barButtonItem {
  1074. if (!_searchViewController) {
  1075. _searchViewController = [[PDFSearchViewController alloc] init];
  1076. }
  1077. _searchViewController.pdfViewController = self;
  1078. [_searchViewController showViewController:self inBarButtonItem:barButtonItem];
  1079. }
  1080. #pragma mark - PDFViewer - BOTA : Bookmarks, Outline,Thumb,Annotation list
  1081. - (void)buttonItemClicked_BOTA:(UIBarButtonItem *)barButtonItem {
  1082. if (!_botaViewController) {
  1083. _botaViewController = [[PDFBOTAViewController alloc] init];
  1084. }
  1085. _botaViewController.pdfViewController = self;
  1086. [_botaViewController showViewController:self inBarButtonItem:barButtonItem];
  1087. }
  1088. #pragma mark - PDFViewer - More : Import / Export XFDF Annotation
  1089. - (void)buttonItemClicked_More:(UIBarButtonItem *)barButtonItem {
  1090. UIAlertAction *exportAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Annotation Export", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
  1091. NSString *xfdfPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"test.xfdf"];
  1092. BOOL result = [self.pdfView.document exportAnnotationToXFDFPath:xfdfPath];
  1093. if (result) {
  1094. NSURL *url = [NSURL fileURLWithPath:xfdfPath];
  1095. UIDocumentInteractionController *documentController = [[UIDocumentInteractionController interactionControllerWithURL:url] retain];
  1096. [documentController presentOpenInMenuFromBarButtonItem:barButtonItem animated:YES];
  1097. }
  1098. }];
  1099. UIAlertAction *importAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Annotation Import", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
  1100. NSURL *samplesURL = [NSBundle.mainBundle.resourceURL URLByAppendingPathComponent:@"Samples"];
  1101. NSString *xfdfPath = [samplesURL.path stringByAppendingPathComponent:@"test.xfdf"];
  1102. BOOL result = [self.pdfView.document importAnnotationFromXFDFPath:xfdfPath];
  1103. if (result) {
  1104. [self.pdfView setNeedsDisplayForVisiblePages];
  1105. }
  1106. }];
  1107. #pragma mark - PDFViewer - More :Add / Delete images and text Watermarks
  1108. UIAlertAction *addWatermarkAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Add Watermark", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
  1109. self.addWaterMarkViewController = [[[PDFAddWaterMarkViewController alloc] initWithDocument:self.pdfView.document] autorelease];
  1110. self.addWaterMarkViewController.delegate = self;
  1111. [self.navigationController pushViewController:self.addWaterMarkViewController animated:YES];
  1112. }];
  1113. #pragma mark - PDFViewer - More :Add / Delte headerfooter and bates
  1114. // Setting headerfooter action
  1115. UIAlertAction *settingHeaderFooter = [UIAlertAction actionWithTitle:NSLocalizedString(@"Setting Headerfooter", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  1116. [self PDFViewPerformSettingHeaderFooter];
  1117. self.navigationItem.rightBarButtonItem.enabled = NO;
  1118. }];
  1119. // Seeting bates action
  1120. UIAlertAction *settingBatesAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Setting Bates",nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  1121. [self PDFViewPerformSettingBates];
  1122. }];
  1123. #pragma mark - PDFView - More :Add / Delete background
  1124. UIAlertAction *addBackgroundAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Add Background", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  1125. PDFBackgroundSettingViewController * addBackgroundViewController = [[[PDFBackgroundSettingViewController alloc] initWithDocument:self.pdfView.document] autorelease];
  1126. [self.pdfView.document retain];
  1127. addBackgroundViewController.delegate = self;
  1128. [self.navigationController pushViewController:addBackgroundViewController animated:YES];
  1129. }];
  1130. #pragma mark - PDFViewer - More : Print
  1131. UIAlertAction *printAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Print", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
  1132. [self PDFViewPerformPrint:self.pdfView];
  1133. }];
  1134. #pragma mark - PDFViewer - More : Flatten
  1135. UIAlertAction *flattenAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Flatten", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
  1136. NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"flatten.pdf"];
  1137. [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
  1138. BOOL result = [self.pdfView.document writeFlattenToURL:[NSURL fileURLWithPath:filePath]];
  1139. if (result) {
  1140. NSURL *url = [NSURL fileURLWithPath:filePath];
  1141. UIDocumentInteractionController *documentController = [[UIDocumentInteractionController interactionControllerWithURL:url] retain];
  1142. [documentController presentOpenInMenuFromBarButtonItem:barButtonItem animated:YES];
  1143. }
  1144. }];
  1145. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil];
  1146. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
  1147. alert.popoverPresentationController.barButtonItem = barButtonItem;
  1148. [alert addAction:flattenAction];
  1149. [alert addAction:printAction];
  1150. [alert addAction:addBackgroundAction];
  1151. [alert addAction:settingHeaderFooter];
  1152. [alert addAction:settingBatesAction];
  1153. [alert addAction:addWatermarkAction];
  1154. [alert addAction:exportAction];
  1155. [alert addAction:importAction];
  1156. [alert addAction:cancelAction];
  1157. [self presentViewController:alert animated:YES completion:nil];
  1158. }
  1159. #pragma mark - PDFViewer - Actions :Add / Delete images HeaderFooter and Bates
  1160. - (void)PDFViewPerformSettingHeaderFooter {
  1161. [self.view addSubview:_headerFooterSetting];
  1162. _headerFooterSetting.translatesAutoresizingMaskIntoConstraints = NO;
  1163. [self.view addConstraints:@[[NSLayoutConstraint constraintWithItem:_headerFooterSetting attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0],[NSLayoutConstraint constraintWithItem:_headerFooterSetting attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0],[NSLayoutConstraint constraintWithItem:_headerFooterSetting attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0],[NSLayoutConstraint constraintWithItem:_headerFooterSetting attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100]]];
  1164. // [_headerFooterSetting mas_remakeConstraints:^(MASConstraintMaker *make) {
  1165. // make.bottom.equalTo(self.view.mas_bottom);
  1166. // make.left.equalTo(self.view.mas_left);
  1167. // make.right.equalTo(self.view.mas_right);
  1168. // make.height.mas_equalTo(100);
  1169. // }];
  1170. [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^ {
  1171. self.headerFooterSetting.center = CGPointMake(self.headerFooterSetting.center.x, self.headerFooterSetting.center.y - 100);
  1172. } completion:nil];
  1173. [_headerFooterSetting.addButton addTarget:self action:@selector(PDFViewPerformAddHeaderFooter:) forControlEvents:UIControlEventTouchUpInside];
  1174. [_headerFooterSetting.deleteButton addTarget:self action:@selector(PDFViewPerformDeleteHeaderFooter:) forControlEvents:UIControlEventTouchUpInside];
  1175. }
  1176. - (void)PDFViewPerformSettingBates {
  1177. [self.view addSubview:_batesSetting];
  1178. _batesSetting.translatesAutoresizingMaskIntoConstraints = NO;
  1179. [self.view addConstraints:@[[NSLayoutConstraint constraintWithItem:_batesSetting attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0],[NSLayoutConstraint constraintWithItem:_batesSetting attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0],[NSLayoutConstraint constraintWithItem:_batesSetting attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0],[NSLayoutConstraint constraintWithItem:_batesSetting attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100]]];
  1180. // [_batesSetting mas_remakeConstraints:^(MASConstraintMaker *make) {
  1181. // make.bottom.equalTo(self.view.mas_bottom);
  1182. // make.left.equalTo(self.view.mas_left);
  1183. // make.right.equalTo(self.view.mas_right);
  1184. // make.height.mas_equalTo(100);
  1185. // }];
  1186. [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^ {
  1187. self.batesSetting.center = CGPointMake(self.batesSetting.center.x, self.batesSetting.center.y - 100);
  1188. } completion:nil];
  1189. [_batesSetting.addButton addTarget:self action:@selector(PDFViewPerformAddBates:) forControlEvents:UIControlEventTouchUpInside];
  1190. [_batesSetting.deleteButton addTarget:self action:@selector(PDFViewPerformDeleteBates:) forControlEvents:UIControlEventTouchUpInside];
  1191. }
  1192. - (void)PDFViewPerformAddHeaderFooter:(UIButton *)btn {
  1193. self.navigationItem.rightBarButtonItem.enabled = YES;
  1194. PDFHeaderFooterAddController *headerFooterControl = [[[PDFHeaderFooterAddController alloc] initWithImage:self.image] autorelease];
  1195. headerFooterControl.delegate = self;
  1196. [self.navigationController pushViewController:headerFooterControl animated:NO];
  1197. [_headerFooterSetting removeFromSuperview];
  1198. }
  1199. - (void)PDFViewPerformDeleteHeaderFooter:(UIButton *)btn {
  1200. self.navigationItem.rightBarButtonItem.enabled = YES;
  1201. [self PDFViewPerformDeleteHeaderFooterAction];
  1202. [_headerFooterSetting removeFromSuperview];
  1203. }
  1204. - (void)PDFViewPerformAddBates:(UIButton *)btn {
  1205. PDFBatesAddViewController *batesAddControl = [[[PDFBatesAddViewController alloc] initWithImage:self.image] autorelease];
  1206. batesAddControl.delegate = self;
  1207. [self.navigationController pushViewController:batesAddControl animated:NO];
  1208. [_batesSetting removeFromSuperview];
  1209. }
  1210. - (void)PDFViewPerformDeleteBates:(UIButton *)btn {
  1211. [self PDFViewPerformDeleteBatesAction];
  1212. [_batesSetting removeFromSuperview];
  1213. }
  1214. // Detele headerfootr action
  1215. - (void)PDFViewPerformDeleteHeaderFooterAction {
  1216. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Delete Page Number", nil) message:NSLocalizedString(@"Are you sure delete all pages number", nil) preferredStyle:UIAlertControllerStyleAlert];
  1217. UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  1218. [self PDFViewPerformDeleteHeaderFooter];
  1219. }];
  1220. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  1221. }];
  1222. [alertController addAction:okAction];
  1223. [alertController addAction:cancelAction];
  1224. [self presentViewController:alertController animated:YES completion:nil];
  1225. }
  1226. // Delete bates action
  1227. - (void)PDFViewPerformDeleteBatesAction {
  1228. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Delete Bates", nil) message:NSLocalizedString(@"Are you sure delete all Bates",nil) preferredStyle:UIAlertControllerStyleAlert];
  1229. UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  1230. [self PDFViewPerformDeleteBates];
  1231. }];
  1232. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  1233. }];
  1234. [alertController addAction:okAction];
  1235. [alertController addAction:cancelAction];
  1236. [self presentViewController:alertController animated:YES completion:nil];
  1237. }
  1238. #pragma mark - CPDFModelDataDelegate
  1239. // Get headerfooter' model to setting page headerfooter's add functional property
  1240. - (void)PDFViewPerformChangeHeaderFooter:(PDFHeaderFooterModel *)modelData {
  1241. CPDFHeaderFooter *headerFooter = [self.pdfView.document headerFooter];
  1242. [headerFooter retain];
  1243. NSString *pageIndex = [NSString stringWithFormat:@"0-%lu",self.pdfView.document.pageCount - 1];
  1244. [pageIndex retain];
  1245. NSString *text = [[[NSString alloc] init] autorelease];
  1246. switch (modelData.fontSelcet) {
  1247. case 0:
  1248. text = [NSString stringWithFormat:@"<<%@>>",modelData.pageStart];
  1249. break;
  1250. case 1:
  1251. text = [NSString stringWithFormat:@"page <<%@>>",modelData.pageStart];
  1252. break;
  1253. case 2:
  1254. text = [NSString stringWithFormat:@"<<%@>>/%lu",modelData.pageStart,self.pdfView.document.pageCount];
  1255. break;
  1256. case 3:
  1257. text = [NSString stringWithFormat:@"<<%@>> of %lu",modelData.pageStart,self.pdfView.document.pageCount];
  1258. break;
  1259. case 4:
  1260. text = [NSString stringWithFormat:@"page <<%@>> of %lu",modelData.pageStart,self.pdfView.document.pageCount];
  1261. break;
  1262. default:
  1263. break;
  1264. }
  1265. headerFooter.pageString = pageIndex;
  1266. [headerFooter setText:text atIndex:modelData.fontPosition];
  1267. [headerFooter setFontSize:modelData.fontSize atIndex:modelData.fontPosition];
  1268. [headerFooter setTextColor:modelData.fontColor atIndex:modelData.fontPosition];
  1269. [headerFooter update];
  1270. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1271. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1272. [headerFooter release];
  1273. [pageIndex release];
  1274. }
  1275. // Get bates' model to setting page bates's add functional property
  1276. - (void)PDFViewPerformChangBates:(PDFHeaderFooterModel *)modelData {
  1277. PDFHeaderFooterModel *modelBatesData = modelData;
  1278. CPDFBates *bates = [self.pdfView.document bates];
  1279. [bates retain];
  1280. NSString *pageIndex = [NSString stringWithFormat:@"%@-%lu",modelBatesData.pageStart,self.pdfView.document.pageCount - 1];
  1281. [pageIndex retain];
  1282. bates.pageString = pageIndex;
  1283. NSString *text = [NSString stringWithFormat:@"<<%@>>",modelBatesData.fontText];
  1284. [text retain];
  1285. [bates setText:text atIndex:modelBatesData.fontPosition];
  1286. [bates setFontName:modelBatesData.fontName atIndex:modelBatesData.fontPosition];
  1287. [bates setFontSize:15.0 atIndex:modelBatesData.fontPosition];
  1288. [bates setTextColor:modelBatesData.fontColor atIndex:modelBatesData.fontPosition];
  1289. [bates update];
  1290. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1291. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1292. [bates release];
  1293. [pageIndex release];
  1294. [text release];
  1295. }
  1296. #pragma mark - WaterMarkModelDataDelegate
  1297. - (void)PDFViewPerformChangeTextWatermark:(PDFWatermarkDataModel *)dataModel {
  1298. CPDFWatermark *textWatermark = [[[CPDFWatermark alloc] initWithDocument:_pdfView.document type:CPDFWatermarkTypeText] autorelease];
  1299. textWatermark.text = dataModel.text;
  1300. textWatermark.textColor = dataModel.textColor;
  1301. textWatermark.opacity = dataModel.watermarkOpacity;
  1302. textWatermark.scale = dataModel.watermarkScale * 2.5;
  1303. textWatermark.isTilePage = dataModel.isTile;
  1304. // textWatermark.tx = dataModel.tx * (_image.size.width / 3) / self.addWaterMarkViewController.textViewController.textPreview.documentImageView.frame.size.width;
  1305. // textWatermark.ty = dataModel.ty * (_image.size.height / 3) / self.addWaterMarkViewController.textViewController.textPreview.documentImageView.frame.size.height;
  1306. textWatermark.rotation = dataModel.watermarkRotation;
  1307. if (textWatermark.isTilePage) {
  1308. textWatermark.verticalSpacing = dataModel.verticalSpacing;
  1309. textWatermark.horizontalSpacing = dataModel.horizontalSpacing;
  1310. }
  1311. if (dataModel.pageString) {
  1312. textWatermark.pageString = dataModel.pageString;
  1313. }
  1314. [_pdfView.document addWatermark:textWatermark];
  1315. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1316. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1317. }
  1318. - (void)PDFViewPerformChangeImageWatermark:(PDFWatermarkDataModel *)dataModel {
  1319. CPDFWatermark *imageWatermark = [[[CPDFWatermark alloc] initWithDocument:_pdfView.document type:CPDFWatermarkTypeImage] autorelease];
  1320. imageWatermark.image = dataModel.image;
  1321. imageWatermark.opacity = dataModel.watermarkOpacity;
  1322. imageWatermark.scale = dataModel.watermarkScale * 2;
  1323. imageWatermark.isTilePage = dataModel.isTile;
  1324. // imageWatermark.tx = dataModel.tx * (_image.size.width / 3) / self.addWaterMarkViewController.imageViewController.imagePreview.documentImageView.frame.size.width;
  1325. // imageWatermark.ty = dataModel.ty * (_image.size.height / 3) / self.addWaterMarkViewController.imageViewController.imagePreview.documentImageView.frame.size.height;
  1326. imageWatermark.rotation = dataModel.watermarkRotation;
  1327. if (imageWatermark.isTilePage) {
  1328. imageWatermark.verticalSpacing = dataModel.verticalSpacing;
  1329. imageWatermark.horizontalSpacing = dataModel.horizontalSpacing;
  1330. }
  1331. if (dataModel.pageString) {
  1332. imageWatermark.pageString = dataModel.pageString;
  1333. }
  1334. [_pdfView.document addWatermark:imageWatermark];
  1335. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1336. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1337. }
  1338. - (void)PDFViewPerformDeleteWatermark:(CPDFWatermark *)waterMark {
  1339. [self.pdfView.document removeWatermark:waterMark];
  1340. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1341. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1342. }
  1343. #pragma mark - BackgroundDataModelDelegate
  1344. - (void)PDFViewPerformChangeBackground:(PDFBackgroundModel *)dataModel {
  1345. CPDFBackground *pageBackground = [_pdfView.document background];
  1346. [pageBackground retain];
  1347. pageBackground.color = dataModel.backgroundColor;
  1348. pageBackground.scale = dataModel.backgroudScale;
  1349. pageBackground.rotation = dataModel.backgroundRotation;
  1350. pageBackground.opacity = dataModel.backgroundOpacity;
  1351. pageBackground.pageString = dataModel.pageString;
  1352. pageBackground.xOffset = dataModel.horizontalSpacing;
  1353. pageBackground.yOffset = dataModel.verticalSpacing;
  1354. pageBackground.isAllowsView = YES;
  1355. pageBackground.isAllowsPrint = YES;
  1356. [pageBackground setImage:dataModel.image];
  1357. [pageBackground update];
  1358. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1359. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1360. [pageBackground release];
  1361. }
  1362. - (void)PDFViewPerformDeleteBackground {
  1363. CPDFBackground *pageBackground = [_pdfView.document background];
  1364. [pageBackground retain];
  1365. [pageBackground clear];
  1366. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1367. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1368. [pageBackground release];
  1369. }
  1370. #pragma mark - Delete Methods
  1371. // Get headerfooter' model to setting page headerfooter's delete functional property
  1372. - (void)PDFViewPerformDeleteHeaderFooter {
  1373. CPDFHeaderFooter *headerFooter = [self.pdfView.document headerFooter];
  1374. [headerFooter retain];
  1375. [headerFooter clear];
  1376. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1377. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1378. [headerFooter release];
  1379. }
  1380. // Get bates' model to setting page bates's delete functional property
  1381. - (void)PDFViewPerformDeleteBates {
  1382. CPDFBates *bates = [self.pdfView.document bates];
  1383. [bates retain];
  1384. [bates clear];
  1385. [self.pdfView.document writeToURL:self.pdfView.document.documentURL];
  1386. [self loadDocumentWithFilePath:self.pdfView.document.documentURL.path completion:nil];
  1387. [bates release];
  1388. }
  1389. #pragma mark - PDFViewer - Page Editor: Split / Extract, Rotate, and delete pages
  1390. - (void)buttonItemClicked_PageEdit:(UIBarButtonItem *)barButtonItem {
  1391. PDFPageEditViewController *vc = [[PDFPageEditViewController alloc] init];
  1392. vc.pdfViewController = self;
  1393. UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
  1394. [self presentViewController:nav animated:YES completion:nil];
  1395. [nav release];
  1396. [vc release];
  1397. }
  1398. #pragma mark - Show/Hide Page Number Indicator
  1399. - (void)showPageNumIndicator {
  1400. if (self.pageNumIndicator.hidden) {
  1401. self.pageNumIndicator.alpha = 0.4;
  1402. self.pageNumIndicator.hidden = NO;
  1403. self.informationIndicator.alpha = 0.4;
  1404. self.informationIndicator.hidden = NO;
  1405. }
  1406. }
  1407. - (void)hidePageNumIndicator {
  1408. if (self.pageNumIndicator.hidden) {
  1409. return;
  1410. }
  1411. [UIView animateWithDuration:0.2 animations:^{
  1412. self.pageNumIndicator.alpha = 0.0;
  1413. self.informationIndicator.alpha = 0.0;
  1414. }completion:^(BOOL finished){
  1415. self.pageNumIndicator.hidden = YES;
  1416. self.informationIndicator.hidden = YES;
  1417. }];
  1418. }
  1419. #pragma mark - PDFViewer - Zoom In / Zoom Out
  1420. - (void)zoomIn:(id)sender {
  1421. if (self.pdfView.scaleFactor >= 6) {
  1422. return;
  1423. }
  1424. self.pdfView.scaleFactor += 1;
  1425. }
  1426. - (void)zoomOut:(id)sender {
  1427. if (self.pdfView.scaleFactor <= 1) {
  1428. return;
  1429. }
  1430. self.pdfView.scaleFactor -= 1;
  1431. }
  1432. #pragma mark - UIImagePickerControllerDelegate
  1433. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
  1434. [picker dismissViewControllerAnimated:YES completion:nil];
  1435. UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
  1436. UIImageOrientation imageOrientation = image.imageOrientation;
  1437. if (imageOrientation != UIImageOrientationUp) {
  1438. UIGraphicsBeginImageContext(image.size);
  1439. [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
  1440. image = UIGraphicsGetImageFromCurrentImageContext();
  1441. UIGraphicsEndImageContext();
  1442. }
  1443. if (self.isCreateFromToolbar) {
  1444. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:self.pdfView.document image:image] autorelease];
  1445. self.pdfView.addAnnotation = annotation;
  1446. } else {
  1447. CPDFStampAnnotation *annotation = [[[CPDFStampAnnotation alloc] initWithDocument:self.pdfView.document image:image] autorelease];
  1448. CGRect bounds = annotation.bounds;
  1449. bounds.origin.x = self.pdfView.menuPoint.x-bounds.size.width/2.0;
  1450. bounds.origin.y = self.pdfView.menuPoint.y-bounds.size.height/2.0;
  1451. annotation.bounds = bounds;
  1452. [self.pdfView addAnnotation:annotation forPage:self.pdfView.menuPage];
  1453. }
  1454. }
  1455. - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
  1456. [picker dismissViewControllerAnimated:YES completion:nil];
  1457. if (self.isCreateFromToolbar) {
  1458. self.pdfView.annotationMode = PDFViewAnnotationModeNone;
  1459. [self.annotationToolbar reloadData];
  1460. }
  1461. }
  1462. #pragma mark - UIPopoverPresentationControllerDelegate
  1463. - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection {
  1464. return UIModalPresentationNone;
  1465. }
  1466. - (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {
  1467. if ([popoverPresentationController.presentedViewController isKindOfClass:[UIAlertController class]]) {
  1468. return;
  1469. }
  1470. self.pdfView.annotationMode = PDFViewAnnotationModeNone;
  1471. [self.annotationToolbar reloadData];
  1472. }
  1473. @end