Повторное использование основанных на коде UIViews по сравнению с XIB - PullRequest
4 голосов
/ 05 февраля 2011

Скажите, что у меня есть 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, я был бы очень признателен.

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

Ответы [ 2 ]

2 голосов
/ 11 февраля 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];

1 голос
/ 05 февраля 2011

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

  1. Создать новый файл XIB
  2. Создать новое представление (в моем случае это была ячейка таблицы)
  3. Установить UIViewController.view в качестве представления (опять же, ячейка таблицы)
  4. Я подключаю его с помощью этого кода (в настоящее время используется в производстве):
    
    @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
    
    
...