UIView и initWithFrame и файл NIB. Как я могу загрузить файл NIB?

У меня есть UIView, называемый baseView, и у меня есть initWithFrame, где я добавляю некоторые другие представления и делаю некоторые настраиваемые вещи. В том же представлении также есть файл NIB.

Теперь у меня есть класс UIViewController с именем AppController, в котором я хочу добавить представление baseView к представлению AppController, поэтому я делаю это:

self.view = baseView;, но проблема в том, что файл NIB не загружается. Как я могу убедиться, что настроенный материал и файл NIB загружены/запущены?

Ответ 1

У вас есть много вариантов, в зависимости от того, как ваш класс baseView предназначен для использования и интеграции в ваше приложение. Неясно, как вы собираетесь использовать этот класс - как представление в подклассе UIViewController или как многократно используемый модульный компонент, который должен быть создан несколько раз в вашем приложении, для использования во многих разных диспетчерах представлений.

Если ваше представление предназначено для единственного представления в подклассе UIViewController, то Phonitive является правильным - свяжите его вместе с подклассом UIViewController.xib и используйте UIViewController viewDidLoad для выполнения окончательной инициализации.

Но если вы хотите, чтобы ваш класс View был многокомпонентным многокомпонентным подкомпонентом в разных контроллерах представлений, интегрированный либо через код, либо через включение в файл .xib для другого контроллера, тогда вам нужно реализовать как метод initWithFrame: init, и awakeFromNib, для обработки обоих случаев. Если ваша внутренняя инициализация всегда включает в себя некоторые объекты из .xib, то в вашем initWithFrame вам нужно будет вручную загрузить .xib, чтобы поддерживать "клиентские" классы, которые хотят создать ваш виджет через код. Аналогичным образом, если файл .xib содержит ваш объект, вам необходимо убедиться, что вы вызываете завершающую обработку кода из awakeFromNib.

Вот пример того, как создать компонент подкласса UIView с дизайном пользовательского интерфейса в банке.

MyView.h:

@interface MyView : UIView
{
    UIView *view;
    UILabel *l;
}
@property (nonatomic, retain) IBOutlet UIView *view;
@property (nonatomic, retain) IBOutlet UILabel *l;

MyView.m:

#import "MyView.h"
@implementation MyView
@synthesize l, view;

- (id)initWithFrame:(CGRect)frame 
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Initialization code.
        //
        [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
        [self addSubview:self.view];
    }
    return self;
}

- (void) awakeFromNib
{
    [super awakeFromNib];

    // commenters report the next line causes infinite recursion, so removing it
    // [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil];
    [self addSubview:self.view];
}

- (void) dealloc
{
     [l release];
     [view release];
     [super dealloc];
}

Здесь выглядит файл nib (за исключением того, что владелец файла должен быть изменен в класс MyView).

enter image description here

обязательно подключите оба устройства представления и метки к файловому владельцу. Это! Шаблон для создания повторно используемых виджетов UIView.

По-настоящему опрятная структура этой структуры заключается в том, что вы можете размещать экземпляры вашего объекта MyView в других файлах nib, просто поместите UIView в нужное место/размер, а затем измените класс в инспекторе идентификации (CMD-4) к MyView и буму, у вас есть экземпляр вашего виджета во всех ваших взглядах! Точно так же, как объекты UIKit, вы можете реализовать делегированные протоколы, чтобы объекты, использующие ваш виджет, могли быть уведомлены о интересных событиях и могут предоставлять данные для отображения в виджетах для его настройки.

Ответ 2

Я нашел это сообщение после проблемы с попыткой сделать это в своем приложении. Я пытался создать экземпляр представления из NIB в методе ViewDidLoad, но элементы управления действовали так, как будто они были отключены. Я боролся с этим, пытаясь напрямую установить свойство userInteractionEnabled и программным образом настроить переключатель сенсорных событий для кнопки в этом представлении. Ничего не получилось. Я наткнулся на другой пост и обнаружил, что viewDidLoad, вероятно, слишком скоро, чтобы загрузить этот NIB. Я переместил нагрузку на метод ViewWillAppear, и все сработало. Надеюсь, это поможет кому-то еще бороться с этим. Главный ответ был отличным и хорошо работает для меня сейчас, когда я его вызываю из нужного места.

Ответ 3

если вы хотите использовать NIB, лучше, чтобы ваш UIView был связан с UIViewController, в этом случае вы можете использовать

UIViewController *vc=[[UIViewController alloc] initWithNibName:@"YourNIBWihtOUTEXTENSION" bundle:nil]

[self.view addSubView:vc.view ];

В случае утечек памяти вам необходимо освободить vc

Ответ 4

Если у вас есть пользовательский UIView с xib файлом.

- (id)initWithFrame:(CGRect)frame
{
   self = [super initWithFrame:frame];

   id mainView;
   if (self)
   {
       NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"HomeAllAdsView" owner:self options:nil];
       mainView = [subviewArray objectAtIndex:0];    
   }
   return mainView;
}

- (void) awakeFromNib
{
   [super awakeFromNib];
}