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


Я создаю приложение, которое использует несколько типов экранов-все они гарантируют наличие собственных пользовательских контроллеров вида. Я успешно переключаюсь между контроллерами вида и их связанными представлениями, переназначая main window ' s 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. Является ли это неправильным способом делать это, и если Итак, как я должен подходить к этому по-другому?

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

2 8

2 ответа:

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

  • Создайте rootViewController как свойство класса с retain.
  • Перед этим:

RootViewController = (UIViewController *) [[BookViewController alloc] init];

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

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

}

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

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

Один отличный способ сделать это-использовать способность UIViewController iOS5+иметь дочерние 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".