Прямые ответы:
- Как указано в ответе @tc., где-то существует разрыв между определением представления в xib и использованием контроллера представления (RightBarButtonItemVC) для определения пользовательского представления в UIBarButtonItem, что проявляется в том факте, что UIViewControllerWrapperView получает buttonPressed вызовите вместо RightBarButtonItemVC. Похоже, что-то не сохраняется, хотя я не уверен, что.
- Далее следует конкретное рабочее решение, которое я реализовал. Я создал категорию, но не для UIViewControllerWrapperView, как упоминалось ранее.
Конкретное решение:
Сначала создайте BarButtonItemLoader, категорию Objective-C в UIViewController:
@interface UIViewController (BarButtonItemLoader)
В UIViewController+BarButtonItemLoader.h определите этот метод:
- (UIBarButtonItem *) rightBarButtonItem;
Поскольку вы не можете отслеживать состояние в категории, определите UIBarButtonItem в AppDelegate.h:
@property (strong, nonatomic) UIBarButtonItem *rightBarButtonItem;
Затем начните реализацию метода rightBarButtonItem категории путем ленивой загрузки rightBarButtonItem из AppDelegate (не забудьте #import "AppDelegate.h"). Это гарантирует, что только один rightBarButtonItem будет создан и сохранен в AppDelegate:
- (UIBarButtonItem *) rightBarButtonItem {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if(!appDelegate.rightBarButtonItem) {
//create a rightBarButtonItem (see below)
}
return appDelegate.rightBarButtonItem;
}
Начните сборку UIView/UIBarButtonItem, для которого будет установлено значение rightBarButtonItem. Перенесите каждый элемент/конфигурацию из старой реализации Interface Builder/xib. Самое главное, обратите внимание на информацию о кадре в инспекторе размера, чтобы вы могли программно расположить свои подпредставления точно так же, как вы разместили их вручную в файле .xib.
- (UIBarButtonItem *) rightBarButtonItem {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if(!appDelegate.rightBarButtonItem) {
UIView *rightBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 264, 44)];
UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightBarView];
UIImageView *textHeader = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"textHeader.png"]];
textHeader.frame = CGRectMake(2, 14, 114, 20);
[rightBarView addSubview:textHeader];
UIButton *button1 = [[UIButton alloc] initWithFrame:CGRectMake(100, 2, 70, 44)];
[button1 setImage:[UIImage imageNamed:@"button1.png"] forState:UIControlStateNormal];
[button1 setImage:[UIImage imageNamed:@"button1Highlighted.png"] forState:UIControlStateHighlighted];
[button1 addTarget:self action:@selector(button1Pressed) forControlEvents:UIControlEventTouchUpInside];
[rightBarView addSubview:button1];
UIButton *button2 = [[UIButton alloc] initWithFrame:CGRectMake(194, 2, 70, 44)];
[button2 setImage:[UIImage imageNamed:@"button2.png"] forState:UIControlStateNormal];
[button2 setImage:[UIImage imageNamed:@"button2Highlighted.png"] forState:UIControlStateHighlighted];
[button2 addTarget:self action:@selector(button2Pressed) forControlEvents:UIControlEventTouchUpInside];
[rightBarView addSubview:button2];
appDelegate.rightBarButtonItem = rightBarButtonItem;
}
return appDelegate.rightBarButtonItem;
}
Наконец, реализуйте методы buttonXPressed в UIViewController+BarButtonItemLoader.m для своих целей:
- (void) button1Pressed {
NSLog(@"button1 Pressed");
}
- (void) button2Pressed {
NSLog(@"button2 Pressed");
}
...
Используйте категорию, добавив этот код в любой UIViewController или его подкласс:
#import "UIViewController+BarButtonItemLoader.h"
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [self rightBarButtonItem];
}
Резюме
Этот подход позволяет вам добавлять UIBarButtonItem на лету в любой UIViewController. Недостатком является то, что вы должны добавить приведенный выше код ко всем создаваемым вами UIViewController.
Другой вариант
Если вы хотите дополнительно инкапсулировать добавление UIBarButtonItems (или чего-то еще), избегая необходимости добавлять код в каждый контроллер представления, вам следует создать BaseViewController, из которого вы затем подклассируете все остальные контроллеры представления. Оттуда вы можете рассмотреть другие элементы, которые вы хотите включить во все ваши контроллеры представления. Выбор маршрута категории или подкласса становится вопросом детализации.
person
kraftydevil
schedule
14.03.2013