Как использовать несколько пользовательских контроллеров iOS без контроллера навигации

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

- (void)changeRootViewController:(NSString *)controllerName
{
    if (controllerName == @"book") {
        rootViewController = (UIViewController *)[[BookViewController alloc] init];
        [self.window setRootViewController:rootViewController];
    } else if (controllerName == @"something_else") {
        // Use a different VC as roowViewController
    }
}

То, как я делаю это, похоже, просто не может быть лучшей практикой. Я не хочу использовать UINavigationController или UITabBarController как rootViewController. Это неправильный способ сделать это, и если да, то как я должен приближаться к этому по-другому?

Я думал, что это было бы где-то покрыто, но (я чувствую себя так), я искал чертову из него, искал связанные вопросы и т.д. Извините, если я что-то пропустил!

Ответ 1

Это не плохое решение. Вы в основном устанавливаете одно представление в виде корневого представления. Когда вам нужен другой UIViewController, вы установите другой. Просто будьте осторожны при утечке...

  • Создайте свойство rootViewController как свойство класса с сохранением.
  • До этого:

rootViewController = (UIViewController *) [[BookViewController alloc] INIT];

Добавьте это:

if(rootViewController){
    self.rootViewController=nil;
}

}

Итак, вы выпускаете предыдущий.

Изменить 1: одно: мое объяснение здесь основано на том, что вы не хотите использовать UINavigationController.

Ответ 2

Один из лучших способов сделать это - это использование возможности iOS5 + UIViewController иметь дочерние UIViewControllers (это называется защитой контроллера просмотра). Мне, конечно, было трудное время, чтобы выяснить, как это сделать, пока я не посмотрю видео WWDC, которое объясняет это очень подробно.

В двух словах он позволяет создать собственный родительский контроллер представлений, которому принадлежит серия контроллеров дочерних представлений. Этот контроллер с одним родительским представлением может (и, вероятно, должен, если вы не делаете какие-то действительно причудливые вещи: P) сидеть в качестве контроллера корневого окна окна приложения. Этот метод наличия одного контроллера представления действует как родительский (и облегчает добавление, удаление и переход дочерних контроллеров), напоминает то, что делает UINavigationController (что является намерением Apple). Теперь вы можете создать свой собственный родительский контроллер просмотра, подобный UINavigationController, но иметь совершенно разные анимации перехода и пользовательский интерфейс.

В качестве примера, в контроллере родительского представления, в viewDidLoad, я добавляю первый дочерний контроллер следующим образом:

self.currentlyDisplayedChildViewController = [[TheFirstViewController alloc] init];
[self addChildViewController:self.currentlyDisplayedChildViewController];
[self.view addSubview:self.currentlyDisplayedChildViewController.view];
[self.currentlyDisplayedChildViewController didMoveToParentViewController:self];

Тогда у меня была бы функция для перехода к следующему контроллеру детского представления (ПРИМЕЧАНИЕ: эта функция принадлежит контроллеру родительского представления - контроллеру представления, который будет действовать как ваш UINavigationController)

- (void)transitionToViewController:(UIViewController *)nextChildViewController
{
    [self addChildViewController:nextChildViewController];
    __weak TheParentViewController *me = self;
    [self transitionFromViewController:self.currentlyDisplayedChildViewController
                      toViewController:nextChildViewController
                              duration:1.0f
                               options:UIViewAnimationOptionTransitionFlipFromLeft
                            animations:nil
                            completion:^(BOOL finished)
                            {
                                [nextChildViewController didMoveToParentViewController:self];
                                [me.currentlyDisplayedChildViewController willMoveToParentViewController:nil];
                                [me.currentlyDisplayedChildViewController removeFromParentViewController];
                                me.currentlyDisplayedChildViewController = nextChildViewController;
                            }];
}

Самое приятное - вы можете использовать все стандартные параметры UIViewAnimationTransition (или определить свою собственную пользовательскую анимацию в блоке анимации. Кроме того, любые события поворота ориентации автоматически перенаправляются с родительского контроллера представления на контроллеры дочерних представлений. одна из самых увлекательных проблем с выполнением собственных манипуляций с контроллером корневого представления.

Я бы предложил посмотреть видео WWDC2011 под названием "Реализация UIViewController Containment".