0

I'm using UIDocumentInteractionController class to preview documents. Is it possible to change the done button for closing the preview with another one? For example I would like to set a different title: "Close" instead of "Done".

Erik B
  • 40,889
  • 25
  • 119
  • 135
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
  • There's a great few answers under a different question if anyone ends up here: http://stackoverflow.com/questions/6855008/change-color-of-uidocumentinteractioncontroller-nav-bar – TahoeWolverine Mar 24 '15 at 19:24

2 Answers2

2

Changing Done button with Finished button Example:

I read that you can get the navigation item from the lastObject and change the left or right buttons.

To change the done button you need to wait for the controller UIDocumentInteractionController view to finish displaying. Sadly there is no method to know that, but there is :

  • (void)documentInteractionControllerWillBeginPreview:(UIDocumentInteractionController *)controller

this will tell you when it begins.

What I do: add a timer and when the controller is ready and then get the navigationbar item button and replace it with a new one.

1) in .h add this delegate and timer

.. UIViewController <UIDocumentInteractionControllerDelegate>
@property (nonatomic, strong) NSTimer *timer;

2) in the .m

#import "UIView+BK.h"

- (void)documentInteractionControllerWillBeginPreview:(UIDocumentInteractionController *)controller{
        //Start timer
        _timer = [NSTimer scheduledTimerWithTimeInterval:.05
                                                  target:self
                                                selector:@selector(checkNavigationBar)
                                                userInfo:_timer
                                                 repeats:YES]; //YES TO CYCLE
    }

- (void) checkNavigationBar
    {
        //get the last view open (the UIDocumentInteractionController View)
        UIView *lastWindow = [[[[UIApplication sharedApplication] keyWindow ] subviews] lastObject];

        //Find the controller the view belongs too. 
        UIViewController *controller = [lastWindow findViewController];

        if (controller) {
            //find navigation bar using a category
            UINavigationBar *bar = [controller.view navigationBarFromView];

            //get the navigationItem
            UINavigationItem *item = bar.topItem;

            //get the done button
            UIBarButtonItem *doneButton = item.leftBarButtonItem ;

            //Creates the new button
            UIBarButtonItem *newDoneButton = [[UIBarButtonItem alloc ]
                                            initWithTitle:@"Finished"
                                            style:UIBarButtonItemStylePlain
                                            target:doneButton.target
                                            action:doneButton.action];

            //change done button
            item.leftBarButtonItem = newDoneButton;

            //Stop timer
            [_timer invalidate];
            _timer = nil;
        }
    }

3) you need this category

header category:

import

@interface UIView (BK)

- (UIViewController *)findViewController;

- (UINavigationBar *)navigationBarFromView;
@end

implementation category:

#import "UIView+BK.h"

@implementation UIView (BK)
- (UIViewController *)findViewController {
    Class vcc = [UIViewController class];    // Called here to avoid calling it iteratively unnecessarily.
    UIResponder *responder = self;
    while ((responder = [responder nextResponder])) if ([responder isKindOfClass: vcc]) return (UIViewController *)responder;
    return nil;
}

- (UINavigationBar *)navigationBarFromView {

    for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:[UINavigationBar  class]]) {
            return (UINavigationBar *)subview;
        }

        UIView *result = [subview navigationBarFromView];
        if (result) {
            return (UINavigationBar *)result;
        }

    }
    return nil;
}
@end
magno cardona
  • 71
  • 1
  • 3
  • 2
    my god... you did all of this to change the wording? I hope it was a demand from a high paying customer for the sake of sanity lol – mafiOSo Jan 20 '14 at 04:04
  • Hi, i've tried this workaround under iOS and it is not working... did you updated this code or found another solution? – Dodgson86 Jul 14 '15 at 10:51
2

I used a QLPreviewController instead of UIDocumentInteractionController and was able to change the "Done" button (QLPreviewController is also called by UIDocumentInteractionController). After presentation of QLPreviewController I found his navigation controller as child view controller at index 0 and then I replaced the left bar button item. Provide your url to QLPreviewController using the datasource delegate.

See also this link

In my viewcontroller.h:

#import <UIKit/UIKit.h>
#import <QuickLook/QuickLook.h>

@interface MyViewController : UIViewController<QLPreviewControllerDataSource>
{    
    // Video preview
    QLPreviewController *_qlPreviewController;
    NSURL *_currentUrl;
}

In my viewcontroller.m:

#import "MyViewController.h"

@implementation MyViewController

/*
    ........
*/

-(void)showDocument
{
    _currentUrl = [NSURL fileURLWithPath:@"path to your document here"];
    _qlPreviewController = [[QLPreviewController alloc] init];
    _qlPreviewController.dataSource = self;
    [self presentViewController:_qlPreviewController animated:true completion:^(void){
        if ([self->_qlPreviewController.childViewControllers count] > 0) {
            UINavigationController *nav = (UINavigationController*) self->_qlPreviewController.childViewControllers[0];
            UIBarButtonItem *origDoneButton = nav.navigationBar.items[0].leftBarButtonItem;
            nav.navigationBar.items[0].leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"MyTitle" style:UIBarButtonItemStyleDone target:origDoneButton.target action:origDoneButton.action];
        }
    }];

}


#pragma mark - QLPreviewControllerDatasource

-(NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
    return 1;
}

-(id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
    return _currentUrl;
}


@end
Drum9791
  • 21
  • 4