开发者

Programming iOS: Document Preview, change the Done button

开发者 https://www.devze.com 2023-03-02 18:40 出处:网络
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 ti

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" i开发者_如何学JAVAnstead of "Done".


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


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
0

精彩评论

暂无评论...
验证码 换一张
取 消