Как мне получить представление в Interface Builder для загрузки пользовательского представления в другом nib?
Я создаю пользовательский виджет, который я хотел бы использовать в нескольких наконечках. Поэтому я создаю новый вид nib Screen3, добавляю несколько кнопок и теперь хочу свой виджет UIAwesomeSauce.
Если я просто добавлю представление, а затем изменим идентификатор класса, он не получит подэлементы из UIAwesomeSauce nib. То же самое, если я пойду в библиотеку и перейду к классам. Кажется, что только UIViewController имеет поле "Load from nib", которое было бы красивым.
Я знаю, что могу загрузить UIAwesomeSauce nib из кода, получить объекты верхнего уровня и поместить его вручную. Но точка IB такова, что вам не нужно размещать вещи в коде. Еще лучше было бы, если бы я мог заставить UIAwesomeSauce появляться в самом списке библиотеки.
РЕШЕННО - Нимрод - ПРОЧИТАЙТЕ ДЛЯ ОБЪЯСНЕНИЯ И КОДА
В любом случае, dood, это здорово. Теперь я могу сделать свои собственные классы виджетов для увлекательных вещей. Сделайте FileOwner вашего UI-ником своего класса, и в нем есть обычный UIView со всеми вашими вещами. (Единственный вид в виджетах ниб не может быть самим классом, или вы получаете рекурсивную функцию в initWithCoder.) Затем в nib вы хотите использовать его, сделайте ванильный UIView и измените его класс. Вы не сможете увидеть виджет внутри этого квадрата, но имеете дело.
Теперь я теперь представляет собой пустой вид, а tMyActualSelf - это единственный вид, в котором вы выполняли работу в другом nib. Ура!
- (id)initWithCoder:(NSCoder*)coder
{
if ((self = [super initWithCoder:coder]))
{
UIView *tMyActualSelf = nil;
// Initialization code
NSArray *tNibItems = [[NSBundle mainBundle] loadNibNamed:@"UIAwesomeSauce" owner:self options:nil];
for (id object in tNibItems)
{
if ([object isKindOfClass:[UIView class]])
tMyActualSelf = (UIView *)[object retain];
}
if( tMyActualSelf )
{
tMyActualSelf.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
[self addSubview:tMyActualSelf];
}
}
return self;
}
Ответы
Ответ 1
Я чувствую вашу боль, когда дело доходит до того, что UIViewController является единственной вещью, с которой вы можете указать загрузку nib, но я думаю, потому что должен быть владелец файла, который является контроллером или что-то в этом роде, хотя я не уверен, почему UIView не может быть владельцем файла.
Я думаю, что вы можете поместить вещи в библиотеку под пользовательскими объектами, но я думаю, что вам будет ограничено размещение UIView там, где класс будет установлен в пользовательский подкласс UIView. Я на самом деле задумался о том, как расширить интерфейс построителя, и похоже, что вы можете сделать это для работы с ОС X, но не для iPhone. Он включает компиляцию кода для нового виджета в построителе интерфейса, чтобы рассказать ему, как рисовать виджет только внутри IB. Я думаю, что на самом деле для этого используется шаблон OS X.
Я думаю, что я, вероятно, сделаю это основной вид в файле nib, который содержит все подъязыки, а затем в initWithCoder: в файле UIAwesomeSauce откройте файл nib, загрузите основной файл и просто поместите его внутри себя так что у вас есть "ненужное" представление между представлением UIAwesomeSauce и subviews (или sub subviews, как это было бы). Я не уверен, насколько это неэффективно, но, возившись с некоторыми вещами, это выглядит как некоторые представления, такие как UIWebView похоже, имеют одно из этих, казалось бы, непрозрачных промежуточных представлений (IIRC).
Если вы придумаете лучшее решение, скажите, пожалуйста, потому что я тоже хотел бы знать.
ИЗМЕНИТЬ
Теперь, когда я смотрю на это, я думаю, что UIView CAN может быть владельцем файла, вы просто не можете установить его в IB. В основном вы бы назвали загрузку nib в подклассе UIView следующим образом:
[bundle loadNibNamed: @ "UISpecialSauce" владелец: self options:...]
Я думаю, что если вы создаете выходы в UISpecialSauce или что-то другое, тогда они должны быть назначены правильно из-за владельца: self.
Ответ 2
Theres cocoapod, который может реально помочь с этим:
https://github.com/mobilejazz/NibWrapper
Он предоставляет представление оболочки, которое загружает дочерний вид из другого NIB. Вы можете указать имя этого встроенного конструктора интерфейса NIB через атрибут runtime.