Как я могу создать Nib со связанным классом представления, который может использоваться несколькими ViewControllers - PullRequest
5 голосов
/ 14 января 2010

Я открываю новый вопрос для продолжения моего последнего ( superview и parentviewcontroller nil после добавления подпредставления ). По сути, я понимаю, что использование подпредставлений - хорошая идея, но у меня не должно быть ViewController, управляющего подпредставлением, которое живет внутри другого ViewController. В основном я хотел бы сделать следующее ... У меня есть два ViewController, которые имеют общее подпредставление. Я создал это подпредставление в виде пера SearchDate.xib. Владельцем файла является соответствующий класс SearchDateView.m / h. У этого класса есть выход для единственного элемента внутри UIView в наконечнике, который является меткой. Класс SearchDateView также имеет функцию для изменения значения метки в SearchDateView.xib. Я бы хотел, чтобы оба моих ViewController загрузили этот кончик, но, видимо, я понятия не имею, как правильно загрузить кончик. Что бы я ни делал, в лучшем случае ничего не отображается, а в худшем - исключение. В документах Apple говорится о перетаскивании других экземпляров классов в IB прямо в ваш основной вид, но это, похоже, не работает. У меня есть выход SearchDateView в моем ViewController, и я попытался сделать это в представлении загрузки контроллера:

searchDateView = [[[NSBundle mainBundle] loadNibNamed:@"SearchDateView" owner:self options:nil] objectAtIndex:0];
[[self view] addSubview:searchDateView];

Но я получаю это исключение:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MainViewController 0x431fac0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key searchDateLabel.'

Я знаю, что делаю что-то не так, но как правильно иметь перо, связанный класс представления, который обновляет некоторые объекты в этом перо и повторно использует этот перо в разных контроллерах?

РЕДАКТИРОВАТЬ: Учитывая комментарий, возможно, это не было достаточно ясно. Я не хочу использовать один и тот же файл пера для ВЕСЬ просмотр - скорее, подвид. Так, например, контроллер A имеет карту, а также SearchDateView, а контроллер B имеет табличное представление и SearchDateView. Поэтому мне интересно, как загрузить подпредставление в несколько контроллеров ...

Ответы [ 2 ]

2 голосов
/ 14 января 2010

Не должно быть проблем с использованием одного и того же файла NIB для нескольких контроллеров, когда каждый из них инициализируется с помощью initWithNibName: bundle :. Обычно вы не загружаете собственный файл пера контроллера изнутри контроллера.

Если вы загрузите nib-файл, используя loadNibNamed :::, вы получите NSArray с определенными в нем объектами, поэтому вы не сможете использовать его как представление напрямую. Один из способов получить представление - это поиск по массиву с помощью for () или чего-то другого, чтобы найти нужный объект, но если вы установили владельца: self, то он должен подключаться к выходам, связанным с владельцем файла самостоятельно, так как владельцем файла будет сам , Но вы можете отказаться от возвращаемого значения в этом случае; вам не нужен возвращаемый массив. Это может быть вашей основной проблемой (засорение розетки массивом), если у вас есть розетка.

Можно использовать loadNibNamed для загрузки определенного объекта представления (при условии, что вы выбрали его из возвращаемого массива), а затем каким-то образом отобразить его, но обычно проще использовать initWithNibName на контроллере (в этом случае владельцем файла будет контроллер).

О, и вы также можете установить файл пера для контроллера в Интерфейсном Разработчике. Не должно быть проблем с использованием одного и того же пера для нескольких контроллеров, поскольку по сути вы просто скажете Интерфейсному Разработчику настроить файл пера для выполнения чего-то вроде initWithNibNamed. Щелкните на объекте контроллера и проверьте окно инспектора.

Обновление

Я бы, вероятно, сделал это, чтобы использовать только одно представление в нескольких контроллерах:

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"FooView" 
                                                 owner:self options:nil];
    for (id obj in nib)
        if ([obj isKindOfClass:[FooView class]])
            myNewView = (FooView *)obj;

(Украдено из главы 8: Ячейки 2 в образце кода из Начало разработки iPhone 3 .)

Вы могли бы сделать это с выходами в IB, и в этом случае вы могли бы пропустить цикл for, но вам, вероятно, понадобится суперкласс для обоих контроллеров, объявляющих выход, и что-то, чтобы сообщить Interface Builder, что Владелец файла является экземпляром этого суперкласса, чтобы он знал о выходе. Вероятно, не стоит хлопот.

0 голосов
/ 16 января 2010

У меня есть выход SearchDateView в моем ViewController, и я попытался сделать это в представлении загрузки контроллера:

searchDateView = [[[NSBundle mainBundle] loadNibNamed:@"SearchDateView" owner:self options:nil] objectAtIndex:0];
[[self view] addSubview:searchDateView];

Но я получаю это исключение:

 *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MainViewController 0x431fac0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key searchDateLabel.'

В отсутствие привязки какао (которая доступна только в Какао, а не в Cocoa Touch), я не думаю, что эти две взаимосвязи.

В Xcode добавьте символическую точку останова на objc_exception_throw, затем запустите ваше приложение в отладчике. Когда он сломается, посмотрите в стек вызовов. Вы сможете найти источник проблемы.

...