Навигация IOS неиерархическая

У меня есть приложение для iOS, использующее iOS 5 и Xcode 4.3.2, которое состоит из 7 контроллеров представления. VC1 связан с VC2, VC2 может быть связан с VC3-VC7, и каждый из этих контроллеров может быть связан друг с другом (подумайте об этом как о боковой панели навигации). Если я использую переходы, представления многократно добавляются в стек, и если пользователь переходит туда и обратно, он может использовать большой объем памяти. Как я могу реализовать эту навигацию, когда я освобождаю предыдущий контроллер? Все они представляют собой небольшие контроллеры, поэтому их загрузка занимает мало времени/процессора/памяти. Могу ли я представить ViewController, а затем каким-то образом освободить PresentingViewController? Спасибо.


person Matt    schedule 06.06.2012    source источник


Ответы (3)


Если вы реализуете UINavigationController, вы можете использовать методы контроллера представления push и pop для перехода туда и обратно. popToViewController:animated: описан здесь вместе с тремя другими полезными методами.

person borrrden    schedule 06.06.2012
comment
Если я использую навигационный контроллер для нажатия и выталкивания представлений, не будет ли перенаправления в потоке программы. Например, входя из VC2, я помещаю VC4 в стек. Теперь пользователь хочет перейти к VC6, поэтому я открываю VC4 (не анимированный) и нажимаю VC6 (анимированный). Не будет ли по-прежнему мигать VC2, когда я выталкиваю VC4 до того, как VC6 будет нажат и отображен? Могу ли я получить эффект перекрестного растворения с помощью навигационного контроллера? - person Matt; 06.06.2012
comment
В этом случае вы можете сначала нажать представление, а затем обновить, напрямую отредактировав свойство viewControllers контроллера навигации (removeObjectAtIndex) - person borrrden; 06.06.2012
comment
Реализовано это решение для управления стеком, избегая дублирования. Контролирует реальное использование памяти приложением. Спасибо. Я бы проголосовал, но у меня пока недостаточно репутации. - person Matt; 06.06.2012

Ну вроде как не должно быть проблем с VC1 на VC2. Для VC3 - VC7 вы можете:

  • Представьте как modalViewController вместо того, чтобы помещать его в стек.

Или: - Используйте функцию popToViewController:animated: вашего UINavigationController, если контроллер уже присутствует в стеке контроллеров, в противном случае нажмите его. Нравиться

// Assuming u need to push VC6
for(UIViewController *controller in [urNavController viewControllers]){
        if([controller isKindOfClass:[VC6 class]])
        {
           [urNavController popToViewController:controller animated:YES];
        }
        else{
            VC6 *VC6controller = [[VC6 alloc] init];
           [urNavController pushViewController:VC6controller];
        }

}
person DennyLou    schedule 06.06.2012
comment
Первоначально у меня были представления, представленные как модальные, но я понимаю, что они помещаются в стек, а затем родительский (или теперь представляющий) контроллер представления отклоняет это представление, когда вы хотите вернуться. В моем случае, входя из VC2, пользователь мог перейти в VC4, а оттуда перейти в VC6, не возвращаясь в VC2. Не будет ли это создавать стек? Ваш вариант навигационного контроллера выглядит интересно. Есть ли быстрый способ добавить навигационный контроллер в мое приложение, не перестраивая его целиком, возможно, из делегата приложения? Я использую раскадровки и ARC BTW. - person Matt; 06.06.2012
comment
Ну, не знаю, если я полностью понял ваше. Есть ли быстрый способ добавить навигационный контроллер в мое приложение, не перестраивая его все, но я бы сначала создал подкласс UINavigationController, например myNavController. В myNavController просто переопределите функцию pushViewController:animated: и добавьте в нее написанный выше код. После этого единственное, что вам нужно сделать, это сделать текущий navController, который вы используете в своем приложении, как myNavController, и вы можете легко проверить, работает ли код, ничего не меняя в своем приложении. ; P надеюсь, что это поможет. - person DennyLou; 06.06.2012
comment
Мое текущее приложение не использовало навигационный контроллер. Я смог быстро добавить его с помощью раскадровки, выбрав «Редактор» -> «Встроить в» -> «Контроллер навигации» в корневом представлении. Это больше для других, которые, возможно, не знали. Я принял другой ответ, поскольку он дал мне возможность действительно контролировать стек, это решение позволило бы загружать все VC один раз (что намного лучше, чем моя первоначальная реализация). - person Matt; 06.06.2012

Вы можете использовать метод - (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated UINavigationController для удаления любых контроллеров представления ниже самого верхнего. Поскольку массив viewControllers навигационного контроллера является неизменяемым, вы не можете использовать какие-либо методы removeObject... NSMutableArray непосредственно в массиве viewControllers. Вам нужно будет превратить mutableCopy в изменяемый массив, удалить любые (скрытые) контроллеры представления, которые вы хотите отбросить из изменяемого массива, и передать полученный уменьшенный стек контроллеров представлений вышеуказанному методу. Поскольку ваш самый верхний контроллер представления не изменится, в вашем случае не будет анимации перехода (см. обсуждение ниже), поэтому вы также можете напрямую установить свойство viewControllers, не беспокоясь об аргументе animated:.

Из документации Apple:

Обсуждение Этот метод можно использовать для обновления или замены текущего стека контроллера представления без явного добавления или извлечения каждого контроллера. Кроме того, этот метод позволяет обновлять набор контроллеров без анимации изменений, что может быть уместно во время запуска, когда вы хотите вернуть контроллер навигации в предыдущее состояние.

Если анимация включена, этот метод решает, какой тип перехода выполнять, основываясь на том, находится ли последний элемент в массиве элементов уже в стеке навигации. Если контроллер представления в настоящее время находится в стеке, но не является самым верхним элементом, этот метод использует всплывающий переход; если это самый верхний элемент, переход не выполняется. Если контроллер представления не находится в стеке, этот метод использует push-переход. Выполняется только один переход, но когда этот переход завершается, все содержимое стека заменяется новыми контроллерами представления. Например, если контроллеры A, B и C находятся в стеке, а вы устанавливаете контроллеры D, A и B, этот метод использует всплывающий переход, и результирующий стек содержит контроллеры D, A и B.

person inwit    schedule 06.06.2012