我在网上看到了很多这样的问题,但似乎没有人真正知道答案?
我正在使用 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]];
最佳答案
我搜索了这个问题的解决方案几个月,终于找到了一种自定义 QLPreviewController 的导航栏的方法。以前我也使用 UIWebView 来显示文档,因为我不允许在我的应用程序中显示某些 secret 文档的 iOS 共享按钮,这就是 QLPreviewController 所做的。但是我想要那些不错的功能,例如带有小预览的目录和其他东西。所以我寻找一种可靠的方法来摆脱这个按钮。和你们一样,我首先考虑自定义 QLPreviewController 的导航栏。然而,正如其他人已经指出的那样,这在 iOS6 之后是绝对不可能的。因此,我们需要做的不是自定义现有的导航栏,而是创建一个自己的导航栏并将其放置在 QL-navigationbar 的前面,从而隐藏它。
那么如何做到这一点呢? 首先,我们需要继承 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]];
}
qlNavigationBar 是 QLPreviewController 拥有的默认导航栏,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;
}
所以现在我们需要实现我们需要的方法来获取 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;
}
}
还有什么?当然,您需要定义属性,在 dealloc 中删除观察者,以及定义和设置 iOS6 属性(网络上有很多示例...)。您还需要自定义导航栏并收听按钮回调。就是这样。
我知道这有点 hacky ...通过将默认 QL 操作按钮隐藏在另一个导航栏下方来隐藏/替换它...但至少它对我来说是可靠的并且您不访问私有(private) API 等。
我在适用于 iOS 6.0 - 7.0 以及 iPad 2 和 3、iPhone 4S 和 5(后者安装了 iOS 7.0 Beta 6)的所有可用模拟器上测试了我的解决方案。
关于iphone - QLPreviewController 删除或添加 UIBarButtonItems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6957091/