// // DITableViewController.m // istanbul // // Created by WindShan on 2017/6/21. // Copyright © 2017年 WindShan. All rights reserved. // #import "DITableViewController.h" @interface DITableViewController (private) - (NSString *)applicationDocumentsDirectory; @end static NSString* documents[] = { @"Text Document.txt", @"Image Document.jpg", @"PDF Document.pdf", @"HTML Document.html" }; #define NUM_DOCS 4 #define kRowHeight 58.0f @implementation DITableViewController @synthesize docWatcher, documentURLs, docInteractionController; #pragma mark - #pragma mark View Controller - (void)setupDocumentControllerWithURL:(NSURL *)url { if (self.docInteractionController == nil) { self.docInteractionController = [UIDocumentInteractionController interactionControllerWithURL:url]; self.docInteractionController.delegate = self; } else { self.docInteractionController.URL = url; } } - (void)viewDidLoad { [super viewDidLoad]; // start monitoring the document directory… self.docWatcher = [DirectoryWatcher watchFolderWithPath:[self applicationDocumentsDirectory] delegate:self]; self.documentURLs = [NSMutableArray array]; // scan for existing documents [self directoryDidChange:self.docWatcher]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return YES; } #pragma mark - #pragma mark UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section == 0) { return NUM_DOCS; } else { return self.documentURLs.count; } } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { NSString *title = nil; if (section == 0) title = @"Example Documents"; else { if (self.documentURLs.count > 0) title = @"Documents folder"; } return title; } - (NSString *)formattedFileSize:(unsigned long long)size { NSString *formattedStr = nil; if (size == 0) formattedStr = @"Empty"; else if (size > 0 && size < 1024) formattedStr = [NSString stringWithFormat:@"%qu bytes", size]; else if (size >= 1024 && size < pow(1024, 2)) formattedStr = [NSString stringWithFormat:@"%.1f KB", (size / 1024.)]; else if (size >= pow(1024, 2) && size < pow(1024, 3)) formattedStr = [NSString stringWithFormat:@"%.2f MB", (size / pow(1024, 2))]; else if (size >= pow(1024, 3)) formattedStr = [NSString stringWithFormat:@"%.3f GB", (size / pow(1024, 3))]; return formattedStr; } // if we installed a custom UIGestureRecognizer (i.e. long-hold), then this would be called - (void)handleLongPress:(UILongPressGestureRecognizer *)longPressGesture { if (longPressGesture.state == UIGestureRecognizerStateBegan) { NSIndexPath *cellIndexPath = [self.tableView indexPathForRowAtPoint:[longPressGesture locationInView:self.tableView]]; NSURL *fileURL; if (cellIndexPath.section == 0) fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:documents[cellIndexPath.row] ofType:nil]]; else fileURL = [self.documentURLs objectAtIndex:cellIndexPath.row]; self.docInteractionController.URL = fileURL; [self.docInteractionController presentOptionsMenuFromRect:longPressGesture.view.frame inView:longPressGesture.view animated:YES]; } } - (UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"cellID"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] ; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } NSURL *fileURL; if (indexPath.section == 0) { // first section is our build-in documents fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:documents[indexPath.row] ofType:nil]]; } else { // second section is the contents of the Documents folder fileURL = [self.documentURLs objectAtIndex:indexPath.row]; } [self setupDocumentControllerWithURL:fileURL]; // layout the cell cell.textLabel.text = [[fileURL path] lastPathComponent]; NSInteger iconCount = [docInteractionController.icons count]; if (iconCount > 0) { cell.imageView.image = [docInteractionController.icons objectAtIndex:iconCount - 1]; } NSError *error; NSString *fileURLString = [self.docInteractionController.URL path]; NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fileURLString error:&error]; NSInteger fileSize = [[fileAttributes objectForKey:NSFileSize] intValue]; cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ - %@", [self formattedFileSize:fileSize], docInteractionController.UTI]; // attach to our view any gesture recognizers that the UIDocumentInteractionController provides //cell.imageView.userInteractionEnabled = YES; //cell.contentView.gestureRecognizers = self.docInteractionController.gestureRecognizers; // // or // add a custom gesture recognizer in lieu of using the canned ones UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; [cell.imageView addGestureRecognizer:longPressGesture]; cell.imageView.userInteractionEnabled = YES; // this is by default NO, so we need to turn it on return cell; } - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return kRowHeight; } #pragma mark - #pragma mark UITableView delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // three ways to present a preview: // 1. Don't implement this method and simply attach the canned gestureRecognizers to the cell // // 2. Don't use canned gesture recognizers and simply use UIDocumentInteractionController's // presentPreviewAnimated: to get a preview for the document associated with this cell // // 3. Use the QLPreviewController to give the user preview access to the document associated // with this cell and all the other documents as well. // for case 2 use this, allowing UIDocumentInteractionController to handle the preview: NSURL *fileURL; if (indexPath.section == 0) { fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:documents[indexPath.row] ofType:nil]]; } else { fileURL = [self.documentURLs objectAtIndex:indexPath.row]; } [self setupDocumentControllerWithURL:fileURL]; // [self.docInteractionController presentPreviewAnimated:YES]; CGRect navRect = self.navigationController.navigationBar.frame; navRect.size = CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT); [self.docInteractionController presentOptionsMenuFromRect:navRect inView:self.view animated:YES]; // for case 3 we use the QuickLook APIs directly to preview the document - // QLPreviewController *previewController = [[QLPreviewController alloc] init]; // previewController.dataSource = self; // previewController.delegate = self; // // // start previewing the document at the current section index // previewController.currentPreviewItemIndex = indexPath.row; // [[self navigationController] pushViewController:previewController animated:YES]; // [previewController release]; } #pragma mark - #pragma mark UIDocumentInteractionControllerDelegate - (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)interactionController { return self; } #pragma mark - #pragma mark QLPreviewControllerDataSource // Returns the number of items that the preview controller should preview - (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)previewController { NSInteger numToPreview = 0; NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; if (selectedIndexPath.section == 0) numToPreview = NUM_DOCS; else numToPreview = self.documentURLs.count; return numToPreview; } - (void)previewControllerDidDismiss:(QLPreviewController *)controller { // if the preview dismissed (done button touched), use this method to post-process previews } // returns the item that the preview controller should preview - (id)previewController:(QLPreviewController *)previewController previewItemAtIndex:(NSInteger)idx { NSURL *fileURL = nil; NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; if (selectedIndexPath.section == 0) { fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:documents[idx] ofType:nil]]; } else { fileURL = [self.documentURLs objectAtIndex:idx]; } return fileURL; } #pragma mark - #pragma mark File system support - (NSString *)applicationDocumentsDirectory { return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; } - (void)directoryDidChange:(DirectoryWatcher *)folderWatcher { [self.documentURLs removeAllObjects]; // clear out the old docs and start over NSString *documentsDirectoryPath = [self applicationDocumentsDirectory]; NSArray *documentsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:NULL]; for (NSString* curFileName in [documentsDirectoryContents objectEnumerator]) { NSString *filePath = [documentsDirectoryPath stringByAppendingPathComponent:curFileName]; NSURL *fileURL = [NSURL fileURLWithPath:filePath]; BOOL isDirectory; [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; // proceed to add the document URL to our list (ignore the "Inbox" folder) if (!(isDirectory && [curFileName isEqualToString: @"Inbox"])) { [self.documentURLs addObject:fileURL]; } } [self.tableView reloadData]; } /* - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath]; // Configure the cell... return cell; } */ /* // Override to support conditional editing of the table view. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the specified item to be editable. return YES; } */ /* // Override to support editing the table view. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete the row from the data source [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } */ /* // Override to support rearranging the table view. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { } */ /* // Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. return YES; } */ /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end