CSearchToolbar.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //
  2. // CSearchToolbar.m
  3. // compdfkit-tools
  4. //
  5. // Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. #import "CSearchToolbar.h"
  13. #import <ComPDFKit/ComPDFKit.h>
  14. #import "CPDFColorUtils.h"
  15. #import "CPDFSearchResultsViewController.h"
  16. #import "CNavigationController.h"
  17. #import "CActivityIndicatorView.h"
  18. #define offset 10
  19. @interface CSearchToolbar()<UISearchBarDelegate>
  20. @property (nonatomic, strong) UIButton *searchListItem;
  21. @property (nonatomic, strong) UIButton *nextListItem;
  22. @property (nonatomic, strong) UIButton *previousItem;
  23. @property (nonatomic, strong) UISearchBar *searchBar;
  24. @property (nonatomic, strong) UIButton *doneItem;
  25. @property (nonatomic, assign) NSInteger nowPageIndex;
  26. @property (nonatomic, assign) NSInteger nowNumber;
  27. @property (nonatomic, strong) NSArray *resultArray;
  28. @property(nonatomic, strong) CPDFView *pdfView;
  29. @property (nonatomic, strong) CActivityIndicatorView *loadingView;
  30. @end
  31. @implementation CSearchToolbar
  32. #pragma mark - Initializers
  33. - (instancetype)initWithPDFView:(CPDFView *)pdfview {
  34. if (self = [super init]) {
  35. self.pdfView = pdfview;
  36. [self commonInit];
  37. self.backgroundColor = [CPDFColorUtils CPDFViewControllerBackgroundColor];
  38. }
  39. return self;
  40. }
  41. - (void)layoutSubviews {
  42. [super layoutSubviews];
  43. _doneItem.frame = CGRectMake(offset, 5, ((self.bounds.size.width - (6*offset)) / 9), 30);
  44. _searchBar.frame = CGRectMake(((self.bounds.size.width - (6*offset)) / 9) + offset*2, 5, ((self.bounds.size.width - (6*offset)) / 9)*5, 30);
  45. _previousItem.frame = CGRectMake(6*((self.bounds.size.width - (6*offset)) / 9) + offset*3, 5, ((self.bounds.size.width - (6*offset)) / 9), 30);
  46. _nextListItem.frame = CGRectMake(self.bounds.size.width - (2*((self.bounds.size.width - (6*offset)) / 9) + 2*offset), 5, ((self.bounds.size.width - (6*offset)) / 9), 30);
  47. _searchListItem.frame = CGRectMake(self.bounds.size.width - (((self.bounds.size.width - (6*offset)) / 9) + offset), 5, ((self.bounds.size.width - (6*offset)) / 9), 30);
  48. }
  49. #pragma mark - Public method
  50. - (void)showInView:(UIView *)subView {
  51. [subView addSubview:self];
  52. self.frame = CGRectMake(0, 0, subView.bounds.size.width, 35);
  53. self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  54. [self.searchBar becomeFirstResponder];
  55. }
  56. - (void)beganSearchText:(NSString *)searchText {
  57. if (![[CPDFKit sharedInstance] allowsFeature:CPDFKitFeatureViewerSearch]) {
  58. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
  59. style:UIAlertActionStyleCancel
  60. handler:nil];
  61. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
  62. message:NSLocalizedString(@"Your license does not support this feature, please upgrade your license privilege.", nil)
  63. preferredStyle:UIAlertControllerStyleAlert];
  64. [alert addAction:cancelAction];
  65. UIViewController *tRootViewControl = [UIApplication sharedApplication].keyWindow.rootViewController;
  66. if ([tRootViewControl presentedViewController]) {
  67. tRootViewControl = [tRootViewControl presentedViewController];
  68. }
  69. [tRootViewControl presentViewController:alert animated:YES completion:nil];
  70. return;
  71. }
  72. if ([searchText length] < 1)
  73. return;
  74. // The search for document characters cannot be repeated
  75. self.window.userInteractionEnabled = NO;
  76. if (![self.loadingView superview]) {
  77. [self.window addSubview:self.loadingView];
  78. }
  79. [self.loadingView startAnimating];
  80. __block __typeof(self) block_self = self;
  81. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  82. NSArray *results = [block_self.pdfView.document findString:searchText withOptions:CPDFSearchCaseInsensitive];
  83. dispatch_async(dispatch_get_main_queue(), ^{
  84. self.window.userInteractionEnabled = YES;
  85. [self.loadingView stopAnimating];
  86. [self.loadingView removeFromSuperview];
  87. block_self.resultArray = results;
  88. dispatch_async(dispatch_get_main_queue(), ^{
  89. if ([block_self.resultArray count] < 1) {
  90. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
  91. style:UIAlertActionStyleCancel
  92. handler:nil];
  93. UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
  94. message:NSLocalizedString(@"Text not found!", nil)
  95. preferredStyle:UIAlertControllerStyleAlert];
  96. UIViewController *tRootViewControl = [UIApplication sharedApplication].keyWindow.rootViewController;
  97. if ([tRootViewControl presentedViewController])
  98. tRootViewControl = [tRootViewControl presentedViewController];
  99. [alert addAction:cancelAction];
  100. [tRootViewControl presentViewController:alert animated:YES completion:nil];
  101. } else {
  102. block_self.nowNumber = 0;
  103. block_self.nowPageIndex = 0;
  104. if(block_self.resultArray.count > block_self.nowPageIndex) {
  105. NSArray *selections = [block_self.resultArray objectAtIndex:block_self.nowPageIndex];
  106. if(selections.count > block_self.nowNumber) {
  107. CPDFSelection *selection = [selections objectAtIndex:block_self.nowNumber];
  108. NSInteger pageIndex = [block_self.pdfView.document indexForPage:selection.page];
  109. [self.pdfView goToPageIndex:pageIndex animated:NO];
  110. [self.pdfView setHighlightedSelection:selection animated:YES];
  111. }
  112. }
  113. }
  114. });
  115. });
  116. });
  117. }
  118. - (void)searchTextNext {
  119. [self buttonItemClicked_Next:nil];
  120. }
  121. - (void)searchTextPrev {
  122. [self buttonItemClicked_Previous:nil];
  123. }
  124. - (void)clearAllSearch {
  125. _resultArray = [[NSArray alloc] init];
  126. self.nowNumber = 0;
  127. self.nowPageIndex = 0;
  128. }
  129. #pragma mark - Accessors
  130. - (UIActivityIndicatorView *)loadingView {
  131. if (!_loadingView) {
  132. _loadingView = [[CActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
  133. _loadingView.center = self.window.center;
  134. _loadingView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
  135. }
  136. return _loadingView;
  137. }
  138. - (NSString *)searchKeyString {
  139. return self.searchBar.text;
  140. }
  141. #pragma mark - Private method
  142. - (void)commonInit{
  143. _searchListItem = [[UIButton alloc] init];
  144. _nextListItem = [[UIButton alloc] init];
  145. _previousItem = [[UIButton alloc] init];
  146. _searchBar = [[UISearchBar alloc] init];
  147. _doneItem = [[UIButton alloc] init];
  148. [self addSubview:self.searchBar];
  149. [self addSubview:self.searchListItem];
  150. [self addSubview:self.nextListItem];
  151. [self addSubview:self.previousItem];
  152. [self addSubview:self.doneItem];
  153. [_doneItem setTitle:NSLocalizedString(@"Done", nil) forState:UIControlStateNormal];
  154. [_doneItem setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  155. _doneItem.titleLabel.adjustsFontSizeToFitWidth = YES;
  156. _searchBar.placeholder = NSLocalizedString(@"Search Text", nil);
  157. UITextField *searchField = [_searchBar valueForKey:@"searchField"];
  158. searchField.adjustsFontSizeToFitWidth = YES;
  159. [_previousItem setImage:[UIImage imageNamed:@"CPDFSearchImagePrevious" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
  160. [_nextListItem setImage:[UIImage imageNamed:@"CPDFSearchImageNext" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
  161. [_searchListItem setImage:[UIImage imageNamed:@"CPDFSearchImageList" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
  162. [self.doneItem addTarget:self action:@selector(buttonItemClicked_Done:) forControlEvents:UIControlEventTouchUpInside];
  163. [self.previousItem addTarget:self action:@selector(buttonItemClicked_Previous:) forControlEvents:UIControlEventTouchUpInside];
  164. [self.nextListItem addTarget:self action:@selector(buttonItemClicked_Next:) forControlEvents:UIControlEventTouchUpInside];
  165. [self.searchListItem addTarget:self action:@selector(buttonItemClicked_SearchList:) forControlEvents:UIControlEventTouchUpInside];
  166. self.searchBar.delegate = self;
  167. }
  168. #pragma mark - Action
  169. - (void)buttonItemClicked_SearchList:(id)sender {
  170. if([self.delegate respondsToSelector:@selector(searchToolbar:onSearchQueryResults:)]) {
  171. [self.delegate searchToolbar:self onSearchQueryResults:self.resultArray];
  172. }
  173. }
  174. - (void)buttonItemClicked_Next:(id)sender {
  175. if (_nowNumber < [self.resultArray[self.nowPageIndex] count] - 1) {
  176. _nowNumber++;
  177. } else {
  178. if (self.nowPageIndex >= self.resultArray.count - 1) {
  179. self.nowNumber = 0;
  180. self.nowPageIndex = 0;
  181. } else {
  182. _nowPageIndex++;
  183. _nowNumber = 0;
  184. }
  185. }
  186. CPDFSelection *selection = self.resultArray[self.nowPageIndex][self.nowNumber];
  187. NSInteger pageIndex = [self.pdfView.document indexForPage:selection.page];
  188. [self.pdfView goToPageIndex:pageIndex animated:NO];
  189. [self.pdfView setHighlightedSelection:selection animated:YES];
  190. }
  191. - (void)buttonItemClicked_Previous:(id)sender {
  192. if (_nowNumber > 0) {
  193. _nowNumber--;
  194. } else {
  195. if (self.nowPageIndex == 0) {
  196. _nowPageIndex = self.resultArray.count - 1;
  197. _nowNumber = [self.resultArray[self.nowPageIndex] count] - 1;
  198. } else {
  199. _nowPageIndex--;
  200. _nowNumber = [self.resultArray[self.nowPageIndex] count] - 1;
  201. }
  202. }
  203. CPDFSelection *selection = self.resultArray[self.nowPageIndex][self.nowNumber];
  204. NSInteger pageIndex = [self.pdfView.document indexForPage:selection.page];
  205. [self.pdfView goToPageIndex:pageIndex animated:NO];
  206. [self.pdfView setHighlightedSelection:selection animated:YES];
  207. }
  208. - (void)buttonItemClicked_Done:(id)sender {
  209. if ([self.delegate respondsToSelector:@selector(searchToolbarOnExitSearch:)])
  210. [self.delegate searchToolbarOnExitSearch:self];
  211. }
  212. #pragma mark - UISearchBarDelegate
  213. - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
  214. [searchBar resignFirstResponder];
  215. NSString *string = searchBar.text;
  216. if ([string length] < 1)
  217. return;
  218. [self beganSearchText:string];
  219. }
  220. @end