как программно установить контроллер представления для подвида в раскадровке?

(Разработано в раскадровке, скриншот ниже) У меня есть два подвида в представлении моего rootviewcontroller.

введите здесь описание изображения

В моем коде я хочу назначить отдельный контроллер представления для каждого подпредставления. i.e Назначьте tableViewController для TableView.

Я пытался сделать это методом awakeFromNib (или ViewDidLoad), но безрезультатно. Метод делегата в моем контроллере tableview никогда не вызывается. Я думаю, что раскадровка выполняет работу по загрузке подпредставлений здесь еще до того, как назначенный мной tableviewcontroller сможет что-то сделать.

self.myTableViewController = (TodoListViewController *)[[UITableViewController alloc]  initWithStyle:UITableViewStylePlain];
self.myTableView.delegate = self.myTableViewController;
self.myTableView.dataSource = self.myTableViewController;
self.myTableViewController.tableView = self.myTableView;

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


person dotnetcoder    schedule 08.07.2012    source источник


Ответы (4)


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

в containerviewcontroller в viewDidLoad я делаю те же вызовы, что и вы (но сначала я определил представление):

self.myTableViewController = (TodoListViewController *)[[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
self.myTableViewController.tableView = self.myTableView;
self.myTableView.delegate = self.myTableViewController;
self.myTableView.dataSource = self.myTableViewController;

Это работает для меня (я думаю, вот ваша проблема: у вас нет навигационного контроллера вокруг него.... и убедитесь, что выходы вашего табличного представления действительно подключены к раскадровке.).

Но настоящая проблема возникает после правильной проводки. Если вы переходите в ячейку, вы, вероятно, захотите передать некоторый идентификатор ячейки для nextView. Поскольку вы определили свой tableviewcontroller вручную, вызывается только ваш метод делегата didSelectRowAtIndexPath, но не метод prepareForSegue.

Я поиграл с созданием экземпляра контроллера представления из раскадровки.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"aStoryboard" bundle:nil];
self.myTableViewController = [storyboard instantiateViewControllerWithIdentifier:@"myTableViewID"];

но segue не вызывался. прямой вызов (performSegueWithIdentifier:...) не сработал, так как этот tableviewcontroller не управляется навигационным контроллером.

Для меня это закончилось тем, что метод prepareForSegue вызывается в containerViewController, который может делегировать вызовы своим подконтроллерам.

РЕДАКТИРОВАТЬ: На самом деле реальным решением является НЕТ. Существует объект «Контейнерное представление», который можно добавить к представлению и который определяет область контроллера представления, которая может включать в себя дочерний контроллер представления. Это то, что я действительно хотел сделать.

person theguy    schedule 20.12.2012
comment
+1 за часть представления контейнера. Именно то, что я ищу. Спасибо. - person Lukman; 31.12.2012

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

Я бы также посмотрел на это: http://blog.waynehartman.com/archive/2012/01/07/uistoryboard-on-ios-5-the-good-the-bad-and-the.aspx

Он показывает наиболее распространенные несчастные случаи, которые люди совершают при программном использовании любой функции раскадровки.

Надеюсь, это поможет!

person user1432813    schedule 08.07.2012
comment
хороший момент, но на данный момент приложение довольно простое и не имеет большого количества кода, который можно было бы перекрыть, как вы указали. поэтому повторная попытка в ViewDidLoad на данный момент не очень помогает. - person dotnetcoder; 09.07.2012

Похоже, вы хотите написать собственный контроллер контейнера, например. аналогично UISplitViewController. Вот краткая документация Apple по этому поводу в ссылка на класс UIViewController. Например, вы можете программно создать дочерние контроллеры в методах viewDidLoad: или viewWillAppear: контроллера контейнера. Я не думаю, что вы можете заставить IB создавать экземпляры дочерних элементов для вас, тем не менее, таким же образом вы можете подключить, скажем, отношения панели вкладок или навигационного контроллера к их дочерним элементам. (Если есть способ, я хотел бы знать!)

person qix    schedule 13.08.2012

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

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

person joshOfAllTrades    schedule 09.07.2012
comment
Спасибо за комментарий. но instanceViewControllerWithIdentifier здесь не помогает, поскольку контроллер представления для табличного представления отсутствует на доске объявлений. Насколько я могу судить, это не позволяет мне назначать контроллер представления для подпредставлений (табличное представление здесь является подпредставлением) и, следовательно, вопрос о SO. - person dotnetcoder; 10.07.2012
comment
Почему бы не сделать это на раскадровке? Раскадровки упрощают объединение вещей. Я пришел из истории желания сделать много в коде по причинам контроля, поэтому я понимаю, если это ваша мотивация, но если вы вообще собираетесь использовать раскадровки, проще просто использовать их полностью. - person joshOfAllTrades; 10.07.2012
comment
позволяет ли раскадровка любить viewcontroller для подвидов? если да, не могли бы вы указать мне в правильном каталоге. По моему опыту, это не позволяет настроить viewcontroller для подвидов. - person dotnetcoder; 10.07.2012
comment
Вероятно, есть и другие способы сделать это, но один из способов сделать это для вашего примера, когда у вас есть одно внешнее представление с двумя внутренними представлениями, каждое из которых имеет свой собственный контроллер, будет иметь 3 контроллера представления на вашей раскадровке. По одному для каждого из ваших дополнительных представлений, полностью подключенных с набором идентификаторов для каждого. И один для внешнего вида. Контроллер внешнего представления в своем viewDidLoad вызовет instanceiateViewControllerWithIdentifier для каждого из контроллеров подчиненного представления, а затем поместит их представления там, где он хочет. Это добавляет «беспорядка» в вашу раскадровку, но каждая часть может быть очень простой. - person joshOfAllTrades; 10.07.2012
comment
1) когда вы говорите «полностью подключенный» - здесь проблема в том, что раскадровка не позволяет подключить vc к подвиду. (2) как упоминалось в сообщении, я уже пытался настроить это в viewDidLoad, но к тому времени подпредставления уже загружены и полностью игнорируют любой назначенный vc в методе viewDidLoad. - person dotnetcoder; 10.07.2012
comment
может быть мой вопрос недостаточно ясен. но, короче говоря, я хочу иметь возможность подключать подвиды в раскадровке. остальное потечет. - person dotnetcoder; 10.07.2012