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".
-
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 Answers
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

- 71
- 1
- 3
-
2my 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
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.
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

- 21
- 4