Подтвердить что ты не робот

Как мне получить представление в 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;
}
4b9b3361

Ответ 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.