Повторное использование UIViews на основе кода по сравнению с XIB

Скажем, у меня есть UIView, который я хотел бы повторно использовать в нескольких контроллерах представления, учитывая, что это довольно общий объект UIView с высокой ценностью повторного использования (например, объект UITextField или UISegmentedControl). Насколько я понимаю, было бы намного проще повторно использовать этот UIView, если бы я написал UIView в коде, а не создавал XIB с помощью Interface Builder. Я пришел к такому выводу, потому что, если UIView написан в коде, я могу просто инициализировать новый экземпляр этого UIView в любом контроллере представления:

MyGreatReusableView *greatReusableView = [[MyGreatReusableView alloc] initWithFrame:CGRectMake(...)];

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

Однако, если я создаю UIView как XIB, он должен быть привязан (либо через владельца файла, либо через IBOutlet объекта View в XIB) к определенному контроллеру представления и, следовательно, может использоваться только в этом контроллере представления. Кроме того, я могу получить доступ к свойствам элементов управления в XIB только с помощью IBOutlets, которые подключены к этому контроллеру представления.

Я думаю, что я совершенно неправильно понял что-то в отношении файлов XIB, так как это кажется довольно большим ограничением! Если бы кто-то мог дать разъяснение о том, возможно ли повторно использовать файлы XIB в нескольких контроллерах представления, и, если да, привести пример решения на основе кода по сравнению с решением на основе XIB, я был бы очень признателен.

Спасибо заранее за любую помощь!


person Skoota    schedule 05.02.2011    source источник


Ответы (2)


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

  1. Создайте новый XIB-файл
  2. Создайте новое представление (в моем случае это была ячейка таблицы)
  3. Установите UIViewController.view как представление (опять же, ячейка таблицы)
  4. I hook it up with this code (currently used in production):
    
    @implementation TableCellFactory
    +(UITableViewCell*) createCellInstanceFromXIBName:(NSString*)name {
            UIViewController* tmp = [[UIViewController alloc] initWithNibName:name bundle:nil];
            UITableViewCell* cell = (UITableViewCell*)[tmp view];
            DebugAssert([[cell class] isSubclassOfClass:[UITableViewCell class]], @"XIB view cell is not a subclass of UITableViewCell; xib name:%@",name);
            DebugAssert(cell != nil,@"cell is nil -- Xib name:%@",name);
            [cell retain];
            [tmp release];
            return cell;
    }
    @end
    
    
person MrAnonymous    schedule 05.02.2011
comment
Спасибо за твое сообщение. Правильно ли я понимаю, что вы создаете контроллер представления, а затем устанавливаете выход представления на этом контроллере для представления XIB исключительно для того, чтобы вы могли получить доступ к свойству .view контроллера представления в коде? Другими словами, сам контроллер представления ничего не делает? Я просто обеспокоен тем, что это не кажется очень элегантным или эффективным решением, поскольку создание UIView в коде означает, что я могу инициализировать UIView напрямую, а не тратить накладные расходы на использование UIViewController. - person Skoota; 06.02.2011
comment
Это верно. Я не теряю сон из-за минимальной неэффективности — это не сложный код, который нужно оптимизировать (по крайней мере, в моем коде). Я считаю, что это также путь, рекомендованный Apple. - person MrAnonymous; 07.02.2011

Альтернативным решением без необходимости установки IBOutlets повторно используемого представления было бы назначение подпредставлений, которые вы хотите использовать, с определенным тегом. Затем вы можете получить просмотры с тегом.

Например, когда вы хотите создать представление с меткой и текстовым полем. Процесс для этого будет следующим:

  1. Создать пустой xib
  2. Настройте представление с меткой и текстовым полем в качестве подпредставления.
  3. Назначьте ярлыку и текстовому полю разные теги (скажем, 10 и 11).

  4. Создайте файл заголовка для этого xib и определите макросы для тегов
    #define kReusableViewNibName @"ReusableViewNibName"
    #define kLabelTag 10
    #define kTextFieldTag 11

  5. Теперь вы можете загрузить xib в любой контроллер представления, который вы хотите:


// Import header file with previous defines

NSArray *rootViewsFromXib = [[NSBundle mainBundle] loadNibNamed:@"NameOfXib"
                                                          owner:nil
                                                        options:nil];

// There is only one root view in the xib,
// the view that contains the label and text field
UIView *loadedView = [rootViewsFromXib objectAtIndex:0];

// You can now use the views from within the xib
// by using the tags to obtain the views.
UILabel *label = (UILabel *)[loadedView viewWithTag:kLabelTag];
UITextField *textField = (UITextField *)[loadedView viewWithTag:kTextFieldTag];

person rsobik    schedule 11.02.2011