UIView.addSubview с использованием представления, загруженного NIB, добавляет только корневой UIView.

Я внедрил компонент в файл XIB, чтобы я мог повторно использовать его в нескольких разных представлениях. Теперь в моем контроллере представления я загружаю UIView на основе XIB и добавляю его к текущему представлению через:

NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"ThumbsPreviewView" owner:self options:nil];
_likePreview = [views objectAtIndex:0];
[self.view addSubview:_likePreview];

Сначала я подумал, что это не работает ... но на самом деле это работает, но только помещает корневой вид (то есть контейнер всех моих графических компонентов, который является прозрачным) для моего вида.

Поэтому мне нужно поместить такой код (для каждого подкомпонента), чтобы он работал:

[self.view addSubview:_likePreview];
NSArray *subviews = _likePreview.subviews;
for(UIView * subview in subviews) {
    [self.view addSubview:subview];
}

Это очень нелогично, и, кроме того, я думаю, что это не создает иерархию представлений, которую я хотел бы.

Я уверен, что есть решение, потому что я сделал то же самое в UITableViewController, чтобы загрузить пользовательский заголовок таблицы из XIB. Использование точно такого же файла XIB в этой ситуации загружает все правильно. Вот код:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    switch(section) {
        case 0: {
            NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"ThumbsPreviewView" owner:self options:nil];
            _likePreview = [views objectAtIndex:0];
            return _likePreview;
        }
    }
    return [super tableView:tableView viewForHeaderInSection:section];
}

С приведенным выше кодом все в порядке, я получил все представление (= контейнер корневого представления со всем его содержимым) в качестве заголовка моего раздела таблицы.

Итак, вопрос: что я делаю неправильно в моем первом примере? Как я могу добавить весь контент (контейнер + весь контент) в мой родительский UIView как правильную иерархию UIView?

РЕДАКТИРОВАТЬ: мне нужно уточнить, что все организовано в моем файле XIB в одном корневом UIView следующим образом (я не могу опубликовать изображение):

* Thumbs preview view
|_ Button
|_ Image View
|_ Image View
|_ Image View
|_ Image View
|_ Button
|_ Button
|_ Button
|_ Label

Спасибо большое за помощь !

Кристоф


person Christophe Fondacci    schedule 16.10.2012    source источник


Ответы (1)


Один из способов загрузить ваш компонент — сохранить ваши компоненты в верхнем объекте UIView (см. прикрепленный снимок экрана).


(источник: mobypicture.com)

Затем вы можете загрузить свой наконечник, как обычно, и использовать -addSubview:, чтобы добавить свои компоненты в иерархию представлений.

РЕДАКТИРОВАТЬ:

Загрузка пера с

UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"testView" owner:self options:nil] objectAtIndex:0];

и добавление представления в иерархию представлений с помощью

[self.view addSubview:view];

приводит к следующей иерархии представлений:

(lldb) po [[self view] recursiveDescription]
(id) $1 = 0x088487b0 <UIView: 0x89595b0; frame = (0 0; 320 548); autoresize = W+H; layer = <CALayer: 0x8958b30>>
   | <UIView: 0x89755c0; frame = (0 0; 320 200); autoresize = RM+BM; layer = <CALayer: 0x8975080>>
   |    | <UIView: 0x8975620; frame = (200 20; 100 30); autoresize = W+H; layer = <CALayer: 0x8975680>>
   |    | <UIView: 0x8975700; frame = (20 20; 100 30); autoresize = W+H; layer = <CALayer: 0x8974ea0>>
   |    | <UIRoundedRectButton: 0x8975790; frame = (20 58; 73 44); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8975890>>
   |    |    | <UIGroupTableViewCellBackground: 0x8976030; frame = (0 0; 73 44); userInteractionEnabled = NO; layer = <CALayer: 0x8976100>>
   |    |    | <UIImageView: 0x89768d0; frame = (1 1; 71 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x89770f0>>
   |    |    | <UIButtonLabel: 0x8977af0; frame = (36 22; 0 0); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8977be0>>
   |    | <UIRoundedRectButton: 0x8978990; frame = (227 58; 73 44); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8978a60>>
   |    |    | <UIGroupTableViewCellBackground: 0x8978a90; frame = (0 0; 73 44); userInteractionEnabled = NO; layer = <CALayer: 0x8978b10>>
   |    |    | <UIImageView: 0x8978b80; frame = (1 1; 71 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8979230>>
   |    |    | <UIButtonLabel: 0x8978be0; frame = (36 22; 0 0); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8978cd0>>
person mkalmes    schedule 16.10.2012
comment
Это именно то, что у меня есть: - person Christophe Fondacci; 16.10.2012
comment
Пожалуйста, проверьте мой отредактированный вопрос. Вы можете проверить сами, загрузив такой XIB и добавив его через [self.view addSubView:loadedNib], вы загрузите только ваше корневое представление и ни одно из его дочерних элементов. - person Christophe Fondacci; 16.10.2012
comment
Загрузка NIB в порядке, проблема возникает при добавлении его в представление: [self.view addSubview:_likePreview]; добавляет только корневой вид. Мне нужно добавить каждое подпредставление по одному: NSArray *subviews = _likePreview.subviews; for(UIView * subview in subviews) { [self.view addSubview:subview]; } - person Christophe Fondacci; 16.10.2012
comment
Как я уже сказал, убедитесь, что ваши UIButtons и UIViews являются прямыми родственниками вашего элемента root-view. Установите точку останова после [self.view addSubview:_likePreview];. Затем введите в отладчик po [[self view] recursiveDescription] и добавьте вывод к своему вопросу. - person mkalmes; 16.10.2012
comment
Возврат этого точно такого же представления в метод UITableViewController viewForHeaderInSection отлично работает (как показано в моем последнем фрагменте кода из моего вопроса), показывая полный компонент (UIView + все подпредставления) в качестве заголовка раздела таблицы, поэтому я уверен, что мой XIB Хорошо, и что каждый компонент является дочерним элементом корневого подпредставления, которое я загружаю. У меня есть только 1 UIView в загруженном массиве UIView, мой корневой вид, затем содержащий все как его дочерний элемент. Опять же, это не работает при вызове addSubView. - person Christophe Fondacci; 16.10.2012
comment
Вы не опубликовали результат recursiveDescription-вызова. - person mkalmes; 16.10.2012
comment
Я воссоздал XIB с нуля, и теперь он работает. Я не делал вызов recursiveDescription на моем бывшем XIB, поэтому я не могу сказать, была ли иерархия правильной, я подозреваю, что это не так. Теперь есть. Это немного странно. В любом случае, спасибо за помощь, теперь я знаю трюк с отладкой recursiveDescription! - person Christophe Fondacci; 16.10.2012