QLPreviewController删除或添加UIBarButtonItems

Jus*_*tin 16 iphone objective-c uibarbuttonitem ipad qlpreviewcontroller

我在互联网上看到了很多这样的问题,但似乎没有人真正知道答案?

我正在使用QLPreviewController来显示PDF文档.我首先使用了UIWebView,但我建议使用QLPreviewController来代替性能较大的文档.

我想要的是右上角的4个自定义UIBarButtonItem(所以打印按钮在哪里).

我设法在底部找到一个自定义工具栏,但这不是我想要的.

考虑到无法在打印按钮的位置添加自定义按钮,我仍然想要删除打印按钮并使用自定义工具栏.

编辑(解决方案): 我刚刚找到解决方案,但没有更新这篇文章,所以这里是我解决问题的方法:

我手动添加按钮:

// Create a toolbar to have the buttons at the right side of the navigationBar
UIToolbar* toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 180, 44.01)];
[toolbar setTranslucent:YES];

// Create the array to hold the buttons, which then gets added to the toolbar
NSMutableArray* buttons = [[NSMutableArray alloc] initWithCapacity:4];


// Create button 1
button1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:@selector(button1Pressed)];
[buttons addObject:button1];

// Create button 2
button2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:@selector(button2Pressed)];
[buttons addObject:button2];

// Create button 3
button3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self action:@selector(button3Pressed)];
[buttons addObject:button3];

// Create a action button
openButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(openWith)];
[buttons addObject:openButton];

// insert the buttons in the toolbar
[toolbar setItems:buttons animated:NO];

// and put the toolbar in the navigation bar
[[self navigationItem] setRightBarButtonItem:[[UIBarButtonItem alloc] initWithCustomView:toolbar]];
Run Code Online (Sandbox Code Playgroud)

Luk*_*oss 27

几个月我搜索了这个问题的解决方案,最后找到了一种方法来自定义QLPreviewController的导航栏.以前我也使用UIWebView来显示文档,因为我不允许在我的应用程序中显示某些机密文档的iOS共享按钮,这就是QLPreviewController的功能.但是我想拥有那些不错的功能,例如目录与小预览和东西.所以我找了一个可靠的方法来摆脱这个按钮.和你们一样,我首先考虑定制QLPreviewController的导航栏.但是,正如其他人已经指出的那样,自iOS6以来这绝对不可能.因此,不是自定义现有的导航栏,而是要创建一个自己的导航栏并将其放在QL导航栏的前面,从而隐藏它.

那怎么做?首先,我们需要子类化QLPreviewContoller并覆盖viewDidAppear方法和viewWillLayoutSubviews,如下所示:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.qlNavigationBar = [self getNavigationBarFromView:self.view];

    self.overlayNavigationBar = [[UINavigationBar alloc] initWithFrame:[self navigationBarFrameForOrientation:[[UIApplication sharedApplication] statusBarOrientation]]];
    self.overlayNavigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    [self.view addSubview:self.overlayNavigationBar];

    NSAssert(self.qlNavigationBar, @"could not find navigation bar");

    if (self.qlNavigationBar) {
        [self.qlNavigationBar addObserver:self forKeyPath:@"hidden" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil];
    }

    // Now initialize your custom navigation bar with whatever items you like...    
    UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:@"Your title goes here"];
    UIBarButtonItem *doneButton  = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneButtonTapped:)];
    item.leftBarButtonItem = doneButton;
    item.hidesBackButton = YES;

    [self.overlayNavigationBar pushNavigationItem:item animated:NO];
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    self.overlayNavigationBar.frame = [self navigationBarFrameForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}
Run Code Online (Sandbox Code Playgroud)

qlNavigationBarQLPreviewController拥有的默认导航栏,overlayNavigationBar是我们的自定义导航栏,它将隐藏默认导航栏.我们还将键值观察添加到默认QL导航栏,以便在默认导航栏被隐藏/重新出现时得到通知.在viewWillLayoutSubviews方法中,我们处理自定义导航框架.

接下来我们应该做的是监听quicklook导航栏的可见性变化:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    // Toggle visiblity of our custom navigation bar according to the ql navigationbar
    self.overlayNavigationBar.hidden = self.qlNavigationBar.isHidden;
}
Run Code Online (Sandbox Code Playgroud)

所以现在我们需要实现获取QL导航栏所需的方法,并且总是为我们的自定义导航栏提供当前帧:

- (UINavigationBar*)getNavigationBarFromView:(UIView *)view {
    // Find the QL Navigationbar
    for (UIView *v in view.subviews) {
        if ([v isKindOfClass:[UINavigationBar class]]) {
            return (UINavigationBar *)v;
        } else {
            UINavigationBar *navigationBar = [self getNavigationBarFromView:v];
            if (navigationBar) {
                return navigationBar;
            }
        }
    }
    return nil;
}

- (CGRect)navigationBarFrameForOrientation:(UIInterfaceOrientation)orientation {
    // We cannot use the frame of qlNavigationBar as it changes position when hidden, also there seems to be a bug in iOS7 concerning qlNavigationBar height in landscape
    return CGRectMake(0.0f, self.isIOS6 ? 20.0f : 0.0f, self.view.bounds.size.width, [self navigationBarHeight:orientation]);
}

- (CGFloat)navigationBarHeight:(UIInterfaceOrientation)orientation {   
    if([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        if(UIInterfaceOrientationIsLandscape(orientation)) {
            return self.isIOS6 ? 32.0f : 52.0f;
        } else {
            return self.isIOS6 ? 44.0f : 64.0f;
        }
    } else {
        return self.isIOS6 ? 44.0f : 64.0f;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有什么?当然,你需要定义属性,删除dealloc中的观察者以及定义和设置iOS6属性(网上有很多例子......).您还需要自定义导航栏并收听按钮回调.而已.

我知道这有点hacky ...隐藏/替换默认的QL操作按钮,将其隐藏在另一个导航栏下...但至少它对我来说是可靠的,你不会访问私有API等.

我在iOS 6.0 - 7.0以及iPad 2和3,iPhone 4S和5(后者安装了iOS 7.0 Beta 6)的所有可用模拟器上测试了我的解决方案.


rbr*_*own 17

更新:

这在iOS 6中不再有效.快速查看在使用XPC的另一个进程中运行.有关详细信息,请参见此处 我没有预见到任何定制QLPreviewController的方法.以下答案适用于对iOS 6之前感兴趣的任何人.


我前几天回答几乎相同的问题在这里.问题在于移除打印按钮,这不是太难.需要注意的一点QLPreviewController是,它不是要定制的.我已经构建了一个QLPreviewController可以自定义的子类.我已经把它放在这里 Github上.它的设计也可以轻松删除动作按钮等功能.用自定义按钮替换按钮不会花费太多精力.

最值得注意的是,只要显示新文档,操作按钮就会重新添加到导航栏.您应该在我的代码中注意到这一点.随时RBFilePreviewer删除操作按钮,您只需重新添加自定义按钮即可.要添加自定义按钮,您应该创建一个UIBarButtonItem包含四个按钮的自定义视图.然后将右侧栏按钮项设置为UIBarButtonItem您创建的自定义项.

更新:

我已更新RBFilePreviewer,允许您开箱即用设置自定义右键栏项目.只要叫-setRightBarButtonItem:RBFilePreviewer,它就可以工作.