iOS 编程:文档预览,更改“完成”按钮

发布于 2024-11-04 16:52:53 字数 115 浏览 0 评论 0原文

我正在使用 UIDocumentInteractionController 类来预览文档。是否可以将关闭预览的完成按钮更改为另一个按钮?例如,我想设置一个不同的标题:“关闭”而不是“完成”。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ぃ弥猫深巷。 2024-11-11 16:52:54

我使用 QLPreviewController 而不是 UIDocumentInteractionController,并且能够更改“完成”按钮(QLPreviewController 也由 UIDocumentInteractionController 调用)。呈现 QLPreviewController 后,我发现他的导航控制器作为索引 0 处的子视图控制器,然后我替换了左栏按钮项。使用数据源委托向 QLPreviewController 提供您的 url。

另请参阅此链接

在我的 viewcontroller.h 中:

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

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

在我的 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

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
空‖城人不在 2024-11-11 16:52:53

用“完成”按钮更改“完成”按钮 示例:

我读到您可以从最后一个对象获取导航项并更改左侧或右侧按钮。

要更改完成按钮,您需要等待控制器 UIDocumentInteractionController 视图完成显示。遗憾的是没有方法可以知道这一点,但是有:

  • (void)documentInteractionControllerWillBeginPreview:(UIDocumentInteractionController *)controller

这会告诉您它何时开始。

我所做的:添加一个计时器,当控制器准备好时,然后获取导航栏项目按钮并将其替换为新按钮。

1) 在 .h 中添加此委托和计时器

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

2) 在 .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) 您需要此类别

标头类别:

导入

@interface UIView (BK)

- (UIViewController *)findViewController;

- (UINavigationBar *)navigationBarFromView;
@end

实现类别:

#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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文