Ответ 1
Нет, нет никакого понятия наследования среди файлов NIB. Единственный вариант - дублировать исходный файл и вносить необходимые изменения в копию.
У меня есть ViewController.xib
, сделанный в IB, который имеет UITableView
.
Я хочу создать еще один xib файл, например. SearchViewController.xib
, наследуемый от ViewController.xib
. Новый SearchViewController.xib должен наследовать UITableView
и дополнительно должен иметь UISearchBar
и UIButton
.
Можно ли создать этот сценарий с помощью Interface Builder?
Нет, нет никакого понятия наследования среди файлов NIB. Единственный вариант - дублировать исходный файл и вносить необходимые изменения в копию.
Вы можете использовать Container View для повторного использования определенного контроллера вида. Таким образом, вам нужно только создать его один раз, добавить логику один раз, и вы можете просто повторно использовать компонент, который вам когда-либо нравится:
Это Документация яблок в представлении контейнера, надеюсь, что это поможет!
Вам понадобятся отдельные .xib файлы или использовать их по умолчанию, а затем программно добавлять элементы управления (например, SearchViewController и т.д.) в код.
Способ думать об этом заключается в том, что XIB файл является сериализованным объектом, а не классом. Экземпляр класса (т.е. Объект) не может быть подклассом, за исключением некоторых языков, основанных на прототипах, таких как Javascript.
Один из способов издеваться над этим - это создать родительский класс типа UIView, который будет загружать XIB и добавлять его к себе (помните, что XIB содержит NSArray визуальных элементов).
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"TestView" owner:self options:nil];
UIView* mainView = (UIView*)[nibViews objectAtIndex:0];
self.label.text = @"Parent";
[self addSubview:mainView];
}
return self;
}
Ребенок может просто переопределить инициализатор как
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.label.text = @"Child";
}
return self;
}
self.label
, конечно, связан с UILabel в файле XIB через построитель интерфейсов и подключен во время выполнения с помощью аргумента owner:self
.
На самом деле проблема должна быть решена в следующих версиях xCode. Поскольку вам нужно написать код, ваш интерфейс должен быть унаследован в других классах, что является кошмаром в случае необходимости изменений позже. Или вы можете копировать/вставьте xib файл, который также станет кошмаром, поскольку вам нужно будет открыть их все и применить модификации
Проблема заключается в том, что подкласс вызывает initWithNibName с именем класса.
Я бы хотел заставить суперкласс загружать суперкласс xib всегда, даже если он унаследован (убедитесь, что выходы находятся в .h суперкласса)
в суперклассе переопределяет initWithNib (он будет вызываться так же, как и обычный init, если вы создали vc vib),
-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:@"NameOfTheSuperClass" bundle:nibBundleOrNil];
if (self) {
}
return self;
}