我的目标是在iOS6的iPad应用程序中使用QLPreviewController,使用顶部工具栏中的自定义操作项按钮。 我有解决方案,直到iOS5.1。我使用了一个扩展QLPreviewController的类,在组件生命周期中我做了类似
的操作[[self navigationItem] setRightBarButtonItems:[NSArray arrayWithObject:[self buildCustomButton]]];
使用iOS6这个技巧不起作用,现在似乎无法改变navigationItem配置。我认为可能涉及到UIActivity和Social Framework的引入,也许在navigationItem上工作并不是更有效,但我可以找到任何解决方案。 有什么建议吗? 谢谢,再见
答案 0 :(得分:6)
我真的需要一个解决方案,所以我做了这个。
是的,这很难看。是的,它可能会在任何时候破裂。是的,我会陷入困境,但我的老板却生气地闭着眼睛盯着我......现在。
@implementation UINavigationItem (Custom)
void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL);
- (void) override_setRightBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated{
if (item && [item.target isKindOfClass:[QLPreviewController class]] && item.action == @selector(actionButtonTapped:)){
QLPreviewController* qlpc = (QLPreviewController*)item.target;
[self override_setRightBarButtonItem:qlpc.navigationItem.rightBarButtonItem animated: animated];
}else{
[self override_setRightBarButtonItem:item animated: animated];
}
}
+ (void)load {
MethodSwizzle(self, @selector(setRightBarButtonItem:animated:), @selector(override_setRightBarButtonItem:animated:));
}
void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL) {
Method origMethod = class_getInstanceMethod(c, origSEL);
Method overrideMethod = class_getInstanceMethod(c, overrideSEL);
if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
}else{
method_exchangeImplementations(origMethod, overrideMethod);
}
}
@end
史蒂夫乔布斯将在我的梦中追捕我,直到找到合适的解决方案......
答案 1 :(得分:2)
好吧,我有好消息和坏消息。
好消息是我已经弄清楚为什么这不起作用。在iOS6中,QLPreviewController的navigationItem不再具有navigationBar:
(lldb) po [[self navigationItem] navigationBar];
(id) $2 = 0x00000000 <nil>
导航栏现在位于QLPreviewControllersView的视图层次结构的深处:
QLPreviewViewController.view-&GT; UIView-&GT; UIView-&GT; QLRemotePreviewContentController-&GT; navBar-&GT; navItem-&GT; rightBarButtonItems
您可以使用以下方法查找您要查找的navigationItem:
- (void)inspectSubviewsForView:(UIView *)view
{
for (UIView *subview in view.subviews)
{
if ([subview isKindOfClass:[UINavigationBar class]])
{
UINavigationBar *bar = (UINavigationBar *)subview;
if ([[bar items] count] > 0)
{
UINavigationItem *navItem = [[bar items] objectAtIndex:0];
[navItem setRightBarButtonItem:nil];
}
}
if ([subview isKindOfClass:[UIView class]] && [[subview subviews] count] > 0)
{
[self inspectSubviewsForView:subview];
}
}
}
只需将[self view]传递给该方法,它就会循环,直到找到相关的标签栏。然后,您可以删除或添加自己的。
坏消息当然是您正在访问私有API,使用此可能会让您的应用被应用商店拒绝。然而,这是我见过的唯一答案。很想知道是否有非私人的方式来做到这一点,但考虑到它的设置方式,似乎不太可能。
此外,此方法仅在条形已经就位后调用时才有效。调用它的最佳位置是'viewDidAppear',但它在100%的时间内都不起作用。
答案 2 :(得分:2)
如果您要更改顶部工具栏中的操作项按钮,则必须在
中执行此操作-(void)viewDidAppear:(BOOL)animated{
//add code necessarry to change your action buttons of toptoolbar in quicklook
}
在视图显示后,可以访问rightBarButtonItems
。
答案 3 :(得分:1)
最好的方法是实现自己的控制器并使用QLPreviewController视图作为子视图。在这种情况下,您可以使用自定义项目创建自己的导航栏。
答案 4 :(得分:0)
我试了很久才更换这个按钮。查看子视图等。看起来这个动作/共享按钮被放置为导航的图层。酒吧。我最后通过在QLPreviewController子类中添加一个按钮而不是title来解决这个问题。
- (void)viewDidLoad
{
[super viewDidLoad];
// Button in center of Navigation Bar
UISegmentedControl *button = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:LS(@"Save"), nil]];
button.frame = CGRectMake(0, 0, 100, 30);
button.center = self.view.center;
button.momentary = YES;
button.segmentedControlStyle = UISegmentedControlStyleBar;
button.tintColor = [UIColor colorWithHue:0.6 saturation:0.33 brightness:0.69 alpha:0];
[button addTarget:self action:@selector(saveToDocumentsClicked) forControlEvents:UIControlEventValueChanged];
self.navigationItem.titleView = button;
}