ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C часть 2

Более детально о навигации

В предыдущих примерах мы уже рассматривали варианты работы с UINavigationController. В этой статье мы более углубимся в тему переходов между контроллерами.

Для начала нам понадобиться создать новый проект. Создадим проект на основе готового шаблона (Navigation-Based Application) в котором имеются связанные контроллер навигации и табличное представление. Я назвал свой проект DetailNavigation. Добавим в проект еще пять классов (контроллеров представления). Вам может показаться, что это много, но в реальных проектах таких контроллеров гораздо больше. Не буду детально описывать процесс добавления классов в проект, поскольку мы уже делали это в примере Контроллер навигаций (UINavigationController). Скажу лишь, что имена классов должно быть:

  • PageOneViewController
  • PageTwoViewController
  • PageThreeViewController
  • PageFourViewController
  • PageFiveViewController

Таким образом, в левой части окна Xcode у вас должна получиться примерно следующая картинка:

 

Продолжаем, теперь в каждом *.xib-файле этих классов добавьте по одной кнопке (она нам нужна будет для навигации).

Пришло время писать код. Измените реализацию класса RootViewController, как это показано ниже.

<code data-result="[object Object]">#import "RootViewController.h"
#import "PageOneViewController.h"

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"Main page";
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.text = @"Main page";
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    PageOneViewController *one = [[PageOneViewController alloc] 
                                  initWithNibName:@"PageOneViewController" bundle:nil];
    [self.navigationController pushViewController:one animated:YES];
    [one release];
}

@end</code>

 

Как видите, пока что ничего нового я здесь не писал. Все эти методы мы рассматривали в предыдущих уроках. Если все сделано правильно — при запуске этой программы в симуляторе вы получите что-то вроде этого:

Давайте проделаем подобную работу для успешной навигации к следующему контроллеру представления. Для этого откройте реализацию класса PageOneViewController и измените его следующим образом:

<code data-result="[object Object]">#import "PageOneViewController.h"
#import "PageTwoViewController.h"

@implementation PageOneViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"One";
}

- (IBAction)press {
    PageTwoViewController *two = [[PageTwoViewController alloc] 
                                  initWithNibName:@"PageTwoViewController" bundle:nil];
    [self.navigationController pushViewController:two animated:YES];
    [two release];
}

@end</code>

 

Добавьте в интерфейс класс PageOneViewController описание метода press и свяжите его с кнопкой, которую вы добавляли ранее (как это делается я уже рассказывал).

Теперь проделайте аналогичную операцию для все остальных контроллеров представления, кроме последнего. Реализацию класса PageFiveViewController я сделал вот такой:

<code data-result="[object Object]">#import "PageFiveViewController.h"

@implementation PageFiveViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"Five";
}

- (IBAction)pressGoToRoot {
    [self.navigationController popToRootViewControllerAnimated:YES];
}

- (IBAction)pressGoToPageTwo {
    NSArray *controllers = self.navigationController.viewControllers;
    [self.navigationController popToViewController:[controllers objectAtIndex:2] animated:YES];
}

@end</code>

 

Добавьте эти два метода в интерфейс класса, затем в *.xib-файл добавьте две кнопки и свяжите их с этими методами. Что же происходит в этих методах? В первом — мы переходим в главный контроллер представления. То есть, чтобы перейти в пятый — нам нужно пройти все контроллеры, которые мы создавали, обычно чтобы вернуться к главному контроллеру мы нажимали бы кнопку «Back» которая расположена на Top Bar. При этом, мы видили бы каждый контроллер представления. Код в методе pressGoToRoot позволяет «перескочить» через все контроллеры представления и попасть к главному, с которого стартовало приложение. Эту возможность контроллера навигации можно использовать в играх или других программах для выхода в главное меню. Единственный параметр, который мы передаем — это логическое значение. Таким образом мы говорим компилятору переход будет сопровождаться анимацией или нет.

В методе pressGoToPageTwo происходит что-то подобное. Мы так же «перескакиваем» через все контроллеры навигации, но не в главный, а тот, что мы указали. Как я уже говорил, контроллер навигации хранит в массиве все контроллеры представления на которые мы переходили. В первой строке этого метода мы получаем этот массив, во второй строке мы вызываем метод popToViewController, а в качестве параметра передаем ему два значения. Первое — это объект с массива, по индексу, который мы указали, а второе — это логическое значения (с анимацией совершать переход или без).

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