Читать книгу iOS. Приемы программирования - Вандад Нахавандипур - Страница 34

Глава 1. Реализация контроллеров и видов
1.16. Представление контроллеров, управляющих несколькими видами, с помощью UITabBarController

Оглавление

Постановка задачи

Необходимо дать пользователям возможность переключаться из одного раздела вашего приложения в другой, причем делать это просто.

Решение

Используйте класс UITabBarController.

Обсуждение

Если вы пользуетесь iPhone как будильником, то, разумеется, замечали на экране панель вкладок. Взгляните на рис. 1.38. В нижней части экрана расположены значки, которые называются World Clock (Мировое время), Alarm (Будильник), Stopwatch (Секундомер) и Timer (Таймер). Вся черная полоса в нижней части экрана – это панель вкладок, а вышеупомянутые ярлыки – ее элементы.

Панель вкладок – это контейнерный контроллер. Это значит, что мы создаем экземпляры UITabBarController и добавляем их в окно нашего приложения. Для каждого элемента панели вкладок мы добавляем на эту панель навигационный контроллер или контроллер вида. Эти элементы будут отображаться как вкладки на панели. Контроллер панели вкладок содержит панель вкладок типа UITabBar. Мы не создаем этот объект вручную – мы создаем контроллер панели вкладок, а уже он создает для нас такой объект. Проще говоря, считайте, что мы инстанцируем контроллер панели вкладок, а потом задаем контроллеры видов для этой панели. Данные контроллеры видов будут относиться к типу UIViewController или UINavigationController, если мы собираемся создать по контроллеру для каждого элемента панели вкладки (они же – контроллеры видов, задаваемые для контроллера панели вкладок). Навигационные контроллеры относятся к типу UINavigationController и являются подклассами от UIViewController. Следовательно, навигационный контроллер – это контроллер вида, но контроллеры видов, относящиеся к типу UIViewController, не являются навигационными контроллерами.

Итак, предположим, что у нас есть два контроллера видов. Классы этих контроллеров называются FirstViewController и SecondViewController:


– (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{


self.window = [[UIWindow alloc] initWithFrame:

[[UIScreen mainScreen] bounds]];


[self.window makeKeyAndVisible];


FirstViewController *firstViewController = [[FirstViewController alloc]

initWithNibName: nil

bundle: NULL];


SecondViewController *secondViewController = [[SecondViewController alloc]

initWithNibName: nil

bundle: NULL];


UITabBarController *tabBarController = [[UITabBarController alloc] init];

[tabBarController setViewControllers:@[firstViewController,

secondViewController

]];


self.window.rootViewController = tabBarController;


return YES;

}


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

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

Первый контроллер вида мы назовем First:

#import "FirstViewController.h"


@implementation FirstViewController


– (id)initWithNibName:(NSString *)nibNameOrNil

bundle:(NSBundle *)nibBundleOrNil{


self = [super initWithNibName: nibNameOrNil

bundle: nibBundleOrNil];

if (self!= nil) {

self.title = @"First";

}

return self;


}


– (void)viewDidLoad{

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];

}


А второй контроллер вида будет называться Second:


#import "SecondViewController.h"


@implementation SecondViewController


– (id)initWithNibName:(NSString *)nibNameOrNil

bundle:(NSBundle *)nibBundleOrNil{


self = [super initWithNibName: nibNameOrNil

bundle: nibBundleOrNil];

if (self!= nil) {

self.title = @"Second";

}

return self;


}


– (void)viewDidLoad{

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];


}


Теперь запустим приложение и посмотрим, что получилось (рис. 1.42).


Рис. 1.42. Очень простая панель вкладок, на которой находятся два контроллера вида


Как видите, у контроллеров видов нет навигационной панели. Что делать? Все просто. Как вы помните, UINavigationController – это подкласс UIViewController. Итак, мы можем добавлять экземпляры навигационных контроллеров на панель вкладок, а внутрь каждого навигационного контроллера загрузить контроллер вида. Чего же мы ждем?


– (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{


// Точка переопределения для специальной настройки,

// выполняемой после запуска приложения.

self.window = [[UIWindow alloc] initWithFrame:

[[UIScreen mainScreen] bounds]];


[self.window makeKeyAndVisible];


FirstViewController *firstViewController = [[FirstViewController alloc]

initWithNibName: nil

bundle: NULL];


UINavigationController *firstNavigationController =

[[UINavigationController alloc]

initWithRootViewController: firstViewController];


SecondViewController *secondViewController = [[SecondViewController alloc]

initWithNibName: nil

bundle: NULL];


UINavigationController *secondNavigationController =

[[UINavigationController alloc]

initWithRootViewController: secondViewController];


UITabBarController *tabBarController = [[UITabBarController alloc] init];


[tabBarController setViewControllers:

@[firstNavigationController, secondNavigationController]];


self.window.rootViewController = tabBarController;


return YES;


}


Что получается? Именно то, что мы хотели (рис. 1.43).


Рис. 1.43. Панель вкладок, на которой контроллеры видов находятся внутри навигационных контроллеров


Как было показано на рис. 1.38, каждый элемент панели вкладок может содержать текст или изображение. Мы узнали, что, пользуясь свойством title контроллера вида, можно задавать такой текст. А что насчет изображения? Оказывается, у каждого контроллера вида есть и свойство tabItem. Это свойство соответствует той вкладке, которая находится в актуальном контроллере вида. Вы можете пользоваться этим свойством, чтобы задавать изображение для вкладки. Изображение для вкладки задается через ее свойство image. Я уже сделал два изображения – прямоугольник и кружок, а теперь выведу их как изображения для вкладок, соответствующих каждому из моих контроллеров видов. Вот код для первого контроллера вида:


– (id)initWithNibName:(NSString *)nibNameOrNil

bundle:(NSBundle *)nibBundleOrNil{


self = [super initWithNibName: nibNameOrNil

bundle: nibBundleOrNil];

if (self!= nil) {

self.title = @"First";

self.tabBarItem.image = [UIImage imageNamed:@"FirstTab"];

}

return self;


}

– (void)viewDidLoad{

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];

}

А вот код для второго контроллера:

– (id)initWithNibName:(NSString *)nibNameOrNil

bundle:(NSBundle *)nibBundleOrNil{


self = [super initWithNibName: nibNameOrNil

bundle: nibBundleOrNil];

if (self!= nil) {

self.title = @"Second";

self.tabBarItem.image = [UIImage imageNamed:@"SecondTab"];

}

return self;


}


– (void)viewDidLoad{

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];

}


Запустив приложение в эмуляторе, увидим такую картинку, как на рис. 1.44.


Рис. 1.44. Элементы панели вкладок с изображениями

iOS. Приемы программирования

Подняться наверх