2013-04-05 5 views
6

Я экспериментирую с тем, как загружать файлы nib в UIViewController.Загрузка файла nib внутри UIViewController

Я создал отдельный файл с пивом под названием Email. Сначала я заметил, что когда контроллер просмотра загружен, метод initWithNibName не вызывается. Так что я назвал его из viewDidLoad метода вручную, как это,

[self initWithNibName:@"Email" bundle:[NSBundle mainBundle]]; 

Это не сработало. Также я получил предупреждение: Результат выражения не использовался.

И я искал в интернете и наткнулся на this статьи и реализован метод loadView, как описано, как это так,

- (void)loadView 
{ 
    [super loadView]; 

    UINib *nib = [UINib nibWithNibName:@"Email" bundle:nil]; 
    [nib instantiateWithOwner:self options:nil]; 
} 

метод вызывается, но до сих пор контроллер представления пуст!

Может кто-нибудь сказать мне, что я здесь не замечаю и как это можно сделать?

Спасибо.

UPDATE:

Во-первых, спасибо за все ответы. Однако voromax и Ответы svena говорят, что я должен удалить segues и загружать nibs автоматически, что я не очень люблю. Ответ Аниль находит, и теперь у меня есть последнее препятствие, чтобы прыгать.

У меня есть несколько файлов nib. В зависимости от выбора пользователя, он должен загружать определенный наконечник. Так что я попытался было, поставить все крупку внутри массива, как это так,

- (void)loadView 
{ 
    [super loadView]; 

    NSArray *nibs = [[NSArray alloc] initWithObjects: 
        [[NSBundle mainBundle] loadNibNamed:@"Facsimile" owner:self options:nil], 
        [[NSBundle mainBundle] loadNibNamed:@"Email" owner:self options:nil], 
        [[NSBundle mainBundle] loadNibNamed:@"Memorandum" owner:self options:nil], 
        [[NSBundle mainBundle] loadNibNamed:@"ProjectMemo" owner:self options:nil], nil]; 


    self.view = [nibs objectAtIndex:0]; 
} 

и доступ к нему, используя его индекс, как этот self.view = [nibs objectAtIndex:1];. Но это вызывает ошибку * Завершение приложения из-за неотображенного исключения «NSInvalidArgumentException», причина: '- [__ NSArrayM _setViewDelegate:]: непризнанный селектор, отправленный в экземпляр 0xd56fd20' *

Почему эта ошибка возникает? Если это невозможно, я открыт для предложений.

Еще раз спасибо. И извините, что немного перетащил это.

+0

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

ответ

1

Вы не должны загружать наконечник для контроллера вида из методов этого контроллера.

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

Если вы ищете крюк внутри представленного контроллера представления, который уже установил бы выходные соединения, переопределение -awakeFromNib является популярным выбором. -viewDidLoad - другой.

Update # 1

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender 
{ 
    if (/*do your segue identification stuff*/) { 
     UIViewController *myViewController = /*init your view controller here*/ 
     UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController]; 
     [self presentViewController:navigationController animated:YES completion:nil]; 
     return NO; 
    } 
    return YES; 
} 
+0

В качестве предыдущего контроллера представлений есть 'UITableViewController', поэтому я попробовал загружать наконечник при создании его непосредственно перед тем, как произойдет segue. 'NewMailViewController * newMailVC = [[NewMailViewController alloc] initWithNibName: @" Email "bundle: nil]; newMailVC = [segue destinationViewController]; 'Но это не сработало. – Isuru

+1

Из вашего комментария Я завершаю, что вы используете раскадровки. Раскадранные экземпляры создают для вас контроллеры просмотра, и вы сами не загружаете эти перья. Есть ли причина, по которой вы хотели бы вернуться к загрузке из nib с помощью раскадровки? – svena

+0

Да, я использую раскадровки. Извините, я должен был упомянуть об этом в вопросе. Сценарий выглядит следующим образом. Я создаю настраиваемое почтовое приложение и существует несколько типов писем. Для каждого типа почты пользовательский интерфейс отличается. Итак, что я сделал, создайте отдельный нить для каждого типа почты, запустите 'UITableViewController', чтобы перечислить типы писем, и когда он отходит, в зависимости от выбора пользователя он загружает определенный файл nib в' UIViewController'. – Isuru

1

Вы должны использовать файл острия для конкретизации самого контроллера представления я. е.

UIViewController *ctrl = [[UIViewController alloc] initWithNibName:@"Email" bundle:nil]; 

После этого вы можете представить этот контроллер

Update

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

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    if (APPROPRIATE_INDEX_PATH) { 
     UIViewController *ctrl = [self.storyboard instantiateViewControllerWithIdentifier:IDENTIFIER]; 
     [self.navigationController pushViewController:ctrl animated:YES]; 
    } 
} 
+0

В качестве предыдущего контроллера представлений есть 'UITableViewController', поэтому я попробовал загружать наконечник при создании его непосредственно перед тем, как произойдет segue. 'NewMailViewController * newMailVC = [[NewMailViewController alloc] initWithNibName: @" Email "bundle: nil]; newMailVC = [segue destinationViewController]; 'Но это не сработало. – Isuru

+1

Вы можете отменить этот сеанс командой '- shouldPerformSegueWithIdentifier: отправитель:' возвращать NO и загружать ваш контроллер вручную. – voromax

9

Используйте следующий код для загрузки вида с пера и использовать в качестве точки зрения контроллера представления

- (void)loadView 
{ 
[super loadView]; 

NSArray *nib =[[NSBundle mainBundle]loadNibNamed:@"test" owner:self options:nil]; 
self.view = [nib objectAtIndex:0]; 
} 

Редактировать

Загрузите один наконечник в соответствии с выбором пользователя. См. Загрузку одного наконечника

NSArray *nib =[[NSBundle mainBundle]loadNibNamed:@"test" owner:self options:nil]; 

возвращает массив объектов. Из вашего обновленного вопроса я вижу, что вы храните эти массивы в другом массиве. Теперь ваш массив nib представляет собой массив объектов «array».

self.view = [[nibs objectAtIndex:0]objectAtIndex:0]; 

будет работать.

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

+0

Спасибо за ответ. Этот метод работает, и у меня есть побочный вопрос. У меня есть несколько файлов nib. В зависимости от выбора пользователя, он должен загружать определенный наконечник. Итак, что я пробовал, поместил все массивы внутри массива, как [this] (http://pastebin.com/rcpHTTSY), и обратился к нему, используя свой индекс liek, этот 'self.view = [nibs objectAtIndex: 1];'. Но это вызывает ошибку _Terminating app из-за неперехваченного исключения «NSInvalidArgumentException», причина: '- [__ NSArrayM _setViewDelegate:]: нераспознанный селектор, отправленный в экземпляр 0xd56fd20'_. Я что-то упустил или есть другой способ сделать это? – Isuru

+0

Можете ли вы разместить свой код вместе с вопросом? Я не могу получить доступ к этой странице. На самом деле массив nib, возвращаемый __loadNib__, содержит не только представление s, он содержит все элементы управления в вашем nib (кнопки/метка ..) objectAtIndex [0] будет объектом верхнего уровня (скорее всего, это представление, если у вас есть один просмотр в СИБ). Не видя свой код, я не могу сказать точную проблему. –

+0

Я обновил свой вопрос выше. – Isuru

Смежные вопросы