// // PDFBookmarkViewController.m // PDFReader // // Copyright © 2014-2022 PDF Technologies, Inc. All Rights Reserved. // // The PDF Reader Sample applications are licensed with a modified BSD license. // Please see License for details. This notice may not be removed from this file. // #import "PDFBookmarkViewController.h" #import "PDFFilterView.h" #import "PDFBookmarkEditViewController.h" @interface PDFBookmarkViewCell : UITableViewCell @property (nonatomic,assign) IBOutlet UILabel *indexLabel; @property (nonatomic,assign) IBOutlet UILabel *titleLabel; @property (nonatomic,assign) IBOutlet UILabel *dateLabel; @end @implementation PDFBookmarkViewCell @end @interface PDFBookmarkViewController () @property (nonatomic,retain) NSArray *bookmarks; @property (nonatomic,retain) UITableView *tableView; @property (nonatomic,retain) UIButton *sortButton; @property (nonatomic,retain) PDFFilterView *filterView; @property (nonatomic,retain) UILabel *noDataLabel; @property (nonatomic,assign) NSInteger sortType; @end @implementation PDFBookmarkViewController #pragma mark - Init Methods - (void)dealloc { [_bookmarks release]; _tableView.delegate = nil; _tableView.dataSource = nil; [_tableView release]; [_sortButton release]; [_filterView release]; [_noDataLabel release]; [super dealloc]; } #pragma mark - UIViewController Methods - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.tableView = [[[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain] autorelease]; self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; self.tableView.dataSource = self; self.tableView.delegate = self; self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 60; self.tableView.tableFooterView = [[[UIView alloc] init] autorelease]; [self.tableView registerNib:[UINib nibWithNibName:@"PDFBookmarkViewCell" bundle:nil] forCellReuseIdentifier:@"cell"]; [self.view addSubview:self.tableView]; self.noDataLabel = [[[UILabel alloc] init] autorelease]; self.noDataLabel.textColor = [UIColor grayColor]; self.noDataLabel.text = NSLocalizedString(@"No bookmarks", nil); [self.noDataLabel sizeToFit]; self.noDataLabel.center = CGPointMake(self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0); self.noDataLabel.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin; [self.view addSubview:self.noDataLabel]; UITableViewHeaderFooterView *filterView = [[[UITableViewHeaderFooterView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)] autorelease]; filterView.autoresizingMask = UIViewAutoresizingFlexibleWidth; filterView.backgroundColor = [UIColor whiteColor]; self.tableView.tableHeaderView = filterView; self.tableView.contentInset = UIEdgeInsetsMake(-44, 0, 0, 0); self.tableView.contentOffset = CGPointMake(0, 44); self.sortButton = [UIButton buttonWithType:UIButtonTypeSystem]; self.sortButton.frame = filterView.bounds; self.sortButton.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; [self.sortButton setTitle:NSLocalizedString(@"Filter", nil) forState:UIControlStateNormal]; [self.sortButton setTitleColor:[UIColor colorWithRed:74.0/255.0 green:74.0/255.0 blue:74.0/255.0 alpha:1.0] forState:UIControlStateNormal]; self.sortButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; self.sortButton.titleEdgeInsets = UIEdgeInsetsMake(0, 15, 0, 0); [self.sortButton addTarget:self action:@selector(buttonItemClicked_Filter:) forControlEvents:UIControlEventTouchUpInside]; [filterView.contentView addSubview:self.sortButton]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.sortButton.bounds.size.width-31, (self.sortButton.bounds.size.height-16)/2.0, 16, 16)]; imageView.image = [UIImage imageNamed:@"btn_bota_more.png"]; imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; [self.sortButton addSubview:imageView]; UIView *line = [[[UIView alloc] initWithFrame:CGRectMake(0, filterView.bounds.size.height-1, filterView.bounds.size.width, 1)] autorelease]; line.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin; line.backgroundColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0]; [filterView addSubview:line]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self reloadData]; } #pragma mark - Button Event Actions - (void)buttonItemClicked_Filter:(id)sender { if (self.filterView) { [self.filterView dismiss]; self.filterView = nil; return; } NSArray *selectedIndexes = nil; if (self.sortType == 0) { selectedIndexes = @[@(0)]; } else if (self.sortType == 1) { selectedIndexes = @[@(1)]; } else if (self.sortType == 2) { selectedIndexes = @[@(2)]; } PDFFilterView *filterView = [[PDFFilterView alloc] init]; filterView.items = @[NSLocalizedString(@"Date", nil), NSLocalizedString(@"Page", nil), NSLocalizedString(@"Title", nil)]; filterView.selectedIndexes = selectedIndexes; filterView.didSelected = ^(NSInteger index) { if (index >= 0) { [self setSelectedIndex:index]; [filterView dismiss]; } self.filterView = nil; }; filterView.frame = CGRectMake(0, 44, self.view.bounds.size.width, self.view.bounds.size.height-44); [filterView showInView:self.view]; [filterView release]; self.filterView = filterView; } - (void)setSelectedIndex:(NSInteger)index { if (index == 0) { self.sortType = 0; [self.sortButton setTitle:NSLocalizedString(@"Date", nil) forState:UIControlStateNormal]; } else if (index == 1) { self.sortType = 1; [self.sortButton setTitle:NSLocalizedString(@"Page", nil) forState:UIControlStateNormal]; } else if (index == 2) { self.sortType = 2; [self.sortButton setTitle:NSLocalizedString(@"Title", nil) forState:UIControlStateNormal]; } [self reloadData]; } - (void)reloadData { self.bookmarks = [self.pdfViewController.pdfView.document bookmarks]; NSInteger (*sortFunction)(id, id, void *) = NULL; const NSInteger bookmarkCount = [self.bookmarks count]; if (self.sortType == 0) { if (bookmarkCount > 1) { sortFunction = sortByDate; } } else if (self.sortType == 1) { if (bookmarkCount > 1) { sortFunction = sortByPage; } } else if (self.sortType == 2) { if (bookmarkCount > 1) { sortFunction = sortByName; } } else { return; } if (sortFunction) { self.bookmarks = [self.bookmarks sortedArrayUsingFunction:sortFunction context:NULL]; } [self.tableView reloadData]; } static NSInteger sortByDate(CPDFBookmark *dict1, CPDFBookmark *dict2, void *context) { return [dict2.date compare:dict1.date]; } static NSInteger sortByPage(CPDFBookmark *dict1, CPDFBookmark *dict2, void *context) { NSInteger value1 = dict1.pageIndex; NSInteger value2 = dict2.pageIndex; if (value1 < value2) { return NSOrderedAscending; } else if (value1 > value2) { return NSOrderedDescending; } else { return NSOrderedSame; } } static NSInteger sortByName(CPDFBookmark *dict1, CPDFBookmark *dict2, void *context) { return [dict1.label compare:dict2.label options:NSCaseInsensitiveSearch]; } #pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (self.bookmarks.count > 0) { self.noDataLabel.hidden = YES; } else { self.noDataLabel.hidden = NO; } return self.bookmarks.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { PDFBookmarkViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; CPDFBookmark *bookmark = self.bookmarks[indexPath.row]; cell.indexLabel.text = [NSString stringWithFormat:@"%ld", bookmark.pageIndex+1]; cell.titleLabel.text = bookmark.label; NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease]; formatter.dateFormat = @"yyyy-MM-dd hh:mm a"; cell.dateLabel.text = [formatter stringFromDate:bookmark.date]; cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; return cell; } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { CPDFBookmark *bookmark = self.bookmarks[indexPath.row]; NSInteger pageIndex = bookmark.pageIndex; [self.pdfViewController.pdfView.document removeBookmarkForPageIndex:pageIndex]; [self reloadData]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { CPDFBookmark *bookmark = self.bookmarks[indexPath.row]; NSInteger pageIndex = bookmark.pageIndex; [self dismissViewControllerAnimated:YES completion:^{ [self.pdfViewController.pdfView goToPageIndex:pageIndex animated:NO]; }]; } - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { CPDFBookmark *bookmark = self.bookmarks[indexPath.row]; PDFBookmarkEditViewController *vc = [[PDFBookmarkEditViewController alloc] init]; vc.text = bookmark.label; vc.callback = ^(NSString *text) { bookmark.label = text; [self reloadData]; }; [self.navigationController pushViewController:vc animated:YES]; [vc release]; } #pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (scrollView == self.tableView) { CGFloat sectionHeaderHeight = 44; if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y >= 0) { scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0); } else if (scrollView.contentOffset.y >= sectionHeaderHeight) { scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0); } else if (scrollView.contentOffset.y <= 0) { scrollView.contentOffset = CGPointMake(0, 0); } } } - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { if (scrollView == self.tableView) { CGFloat sectionHeaderHeight = 44; if (scrollView.contentOffset.y >= 0 && scrollView.contentOffset.y <= sectionHeaderHeight/2.0) { [UIView animateWithDuration:0.3 animations:^{ scrollView.contentOffset = CGPointMake(0, 0); }]; } else if (scrollView.contentOffset.y >= sectionHeaderHeight/2.0 && scrollView.contentOffset.y <= sectionHeaderHeight) { [UIView animateWithDuration:0.3 animations:^{ scrollView.contentOffset = CGPointMake(0, sectionHeaderHeight); }]; } } } @end