Не удалось pushViewController для подвида

У меня есть UINavigationController, и у меня есть отдельные UIViews, между которыми я переключаюсь с помощью UISegmentControl. При переключении представлений я добавляю представление в качестве подпредставления к представлению моего навигационного контроллера:

[self.view addSubview:segmentTab1.view];

и

[self.view addSubview:segmentTab2.view];

Затем в subViews у каждого есть UITableView, но моя проблема в том, что я не могу вставить новый viewController в представление в методе didSelectRowAtIndexPath.

Метод вызывается правильно, и, установив точки останова, я вижу, что метод для нажатия на представление также вызывается, но ничего не происходит. Это мой код для его нажатия:

[self.navigationController pushViewController:detailsViewController animated:YES];

я тоже пробовал

[super.navigationController pushViewController:detailsViewController animated:YES];

Что я делаю не так - или это просто невозможно сделать с подвидом?


person runmad    schedule 06.11.2009    source источник


Ответы (5)


Когда вы вызываете -pushViewController, какой контроллер представления является самостоятельным? Если вы вызываете это из одного из ваших подвидов вкладок, у self, вероятно, нет ссылки на контроллер навигации из представления верхнего уровня, в которое вы его добавили. Вы можете проверить это, получив адрес памяти навигационного контроллера из представления верхнего уровня и сравнив его с тем, что у вас есть в подпредставлении. Очевидно, что если он равен нулю или не совпадает, то это ваша проблема.

Вы получаете навигационный контроллер «бесплатно» только тогда, когда он был добавлен в сам навигационный стек с помощью -pushViewController, в котором ваши подпредставления не были добавлены таким образом.

person Matt Long    schedule 06.11.2009
comment
Именно так — вызов pushViewController должен исходить из представления, которое само было помещено в навигационный контроллер. Он не обязательно должен быть отправлен последним, но он ДОЛЖЕН находиться в стеке навигационных контроллеров. - person Amagrammer; 06.11.2009
comment
Уточнение: должно исходить из КОНТРОЛЛЕРА представления, а не представления. - person Amagrammer; 06.11.2009
comment
Спасибо, Мэтт. И «Амаграммамер». У меня есть вкладки с навигационными контроллерами в каждой, у которых есть перо и класс, прикрепленный к их представлениям. Я собираюсь настроить его так, чтобы каждая вкладка имела контроллер представления, и в каждом из контроллеров представления я добавляю UINavigationController, который переключает представления на основе segmentedControl, и, надеюсь, я смогу добавить подпредставления, когда доберусь туда: ) - person runmad; 06.11.2009
comment
В основном. Приложение App Store для iPhone — пример того, чего я хочу достичь. TabBar, каждый с UINavigationController, который имеет segmentedController (по крайней мере, некоторые из них), и строки могут быть нажаты. - person runmad; 06.11.2009
comment
Я согласен, когда вы добавляете подпредставление в существующее представление, оно не будет включать ссылку на контроллер навигации, а ваши вызовы pushViewController:animated: будут отправлены на ноль и проигнорированы. Интересно, что приложение App Store (и несколько других) выглядит так, как будто они используют сегментированные элементы управления для фильтрации данных таблицы в одном пера, а не как выбор между разными пера (по сути, представление вкладки). - person crafterm; 21.04.2010
comment
Но не могли бы вы подробно объяснить мне, как вызвать другой экран из подвида. У меня именно эта проблема. - person dinesh; 13.01.2012

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

Во всех viewController

- (void)viewWillAppear:(BOOL)animated {

    [self.view addSubview:[[(NavAppAppDelegate *)[[UIApplication sharedApplication] delegate] headerview] view]];
    [[(NavAppAppDelegate *)[[UIApplication sharedApplication] delegate] headerview] viewWillAppear:YES];

}

Я сослался на следующий пост, чтобы реализовать представление заголовка Common XIB в нескольких контроллерах представления в iPhone

[self.view addSubview:[[(NavAppAppDelegate *)[[UIApplication sharedApplication] delegate] headerview] view]];     // line will load the header subview 

[[(NavAppAppDelegate *)[[UIApplication sharedApplication] делегат] headerview] viewWillAppear:YES]; // это вызов метода viewWillAppear класса HeaderController, где мы можем написать код для проверки, зарегистрирован пользователь или нет, и изменить кнопку входа в систему на кнопку выхода из системы и т. д.

person Rijesh    schedule 03.11.2012

Вместо

[self.view addSubview:segmentTab1.view];

и

[self.view addSubview:segmentTab2.view];

вы можете использовать

[self pushViewController: segmentTab1 animated: NO];

и

[self pushViewController: segmentTab2 animated: NO];

чтобы добавить свои viewControllers в навигационную иерархию и заставить [super.navigationController pushViewController:detailsViewController animated:YES]; работать.

person luvieere    schedule 06.11.2009
comment
Не уверен, что это сработает, но если вы переключите представления в segmentController и используете TabBar, нажатие tabBarItem для этого представления отодвинет представление назад. Выглядит не очень :( - person runmad; 06.11.2009
comment
Я не уверен, что правильно понимаю это поведение. Возможно, вам следует посмотреть на свойство visibleViewController навигационного контроллера, и если оно соответствует представлению, которое вы пытаетесь отправить, больше не нажимайте его. - person luvieere; 06.11.2009

Мне не совсем понятно, какова ваша иерархия представлений, но в целом, если представление ваших навигационных контроллеров не является первым подпредставлением окна или элементом одного из представлений коллекции Apple (либо представление содержимого другого навигационного представления, либо представление контроллера вкладок просмотр содержимого) он не будет работать правильно.

person Louis Gerbarg    schedule 06.11.2009

Одна из возможностей, если вы не против одиночек, состоит в том, чтобы сделать объект UINavigationController вашего продукта одноэлементным, доступным (например) из вашего делегата приложения.

Вы бы вызвали его таким образом:

[[((MyApplicationDelegate*)[UIApplication delegate]) navController] 
                pushViewController: viewControllerToPush animated: YES];

где в MyApplicationDelegate navController возвращает одноэлементный объект.

person Amagrammer    schedule 06.11.2009