Пользовательская кнопка навигации Item с QLPreviewController в iOS6
Моя цель - использовать QLPreviewController в моем приложении для iPad для iOS6, используя мою пользовательскую кнопку "Действие" на верхней панели инструментов. У меня было решение до iOS5.1. Я использовал класс, который расширяет QLPreviewController и во время жизненного цикла компонента я сделал что-то вроде
[[self navigationItem] setRightBarButtonItems:[NSArray arrayWithObject:[self buildCustomButton]]];
В iOS6 этот прием больше не работает, и теперь кажется невозможным изменить конфигурацию навигационного элемента. Я думаю, что внедрение UIActivity и Social Framework может быть вовлечено, и, возможно, работать с навигационным элементом не так эффективно, но я могу найти любое решение. Любое предложение? Спасибо пока
5 ответов
Мне действительно очень нужно решение, поэтому я придумал это.
Да, это некрасиво. Да, это может сломаться в любое время. И да, я пойду прямо в ад, но мой босс перестал смотреть на меня злыми глазами... пока.
@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
Стив Джобс будет охотиться на меня во сне, пока я не найду правильное решение...
Ну, у меня есть хорошие новости и плохие новости.
Хорошая новость в том, что я понял, почему это не работает. В iOS6 у элемента навигации QLPreviewController больше нет навигационной панели:
(lldb) po [[self navigationItem] navigationBar];
(id) $2 = 0x00000000 <nil>
Панель навигации теперь расположена глубоко в иерархии представления QLPreviewControllersView:
QLPreviewViewController.view-> UIView-> UIView-> QLRemotePreviewContentController-> NAVBAR->navItem->rightBarButtonItems.
Вы можете использовать метод ниже, чтобы найти навигационный элемент, который вы ищете:
- (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% времени.
Это работает, если вы меняете кнопку элемента действия на верхней панели инструментов, вам придется сделать это внутри
-(void)viewDidAppear:(BOOL)animated{
//add code necessarry to change your action buttons of toptoolbar in quicklook
}
После того, как вид появляется rightBarButtonItems
можно получить доступ
Лучший способ - реализовать собственный контроллер и использовать представление QLPreviewController в качестве подпредставления. В этом случае вы можете сделать свою собственную панель навигации с пользовательскими элементами.
Я долго пытался заменить эту кнопку. Посмотрел подпредставления и т. Д. Похоже, что эта кнопка действия / поделиться помещается как слой в навигацию. бар. Я решил эту проблему для себя, добавив еще одну кнопку вместо заголовка в подклассе QLPreviewController.
- (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;
}