Ancient Frog - лягушачьи лапки… Уроки iPhone SDK: Создаем пазл для iPhone
Май 21

В этом уроке мы узнаем, как добавить в приложение с контроллером навигации “UINavigationController” элемент интерфейса “UIToolbar“. Передо мной стояла задача добавления этой панели в интерфейс одной кнопкой. Щелчок на кнопке должен был загружать контроллер представления, тот же самый что и при выборе “UITableViewCell“. Ниже описано найденное мною решение.

Вот как будет выглядеть готовое приложение:

app1

Для начала создайте новый проект, выбрав опцию “Navigation-Based Application“. Откройте заголовочный файл для “RootViewController” и добавьте переменную типа “UIToolbar” и “UINavigationController“. Вот как в итоге будет выглядеть файл (без комментариев). Одновременно мы создаем еще две переменных того же контроллера “UIViewController” — подробнее на этом моменте мы остановимся ниже.

1
2
3
4
5
6
7
8
9
10
11
12
13
#import <UIKit/UIKit.h>

@class InfoViewController;

@interface RootViewController : UITableViewController {

UIToolbar *toolbar;
InfoViewController *ivControllerToolbar;
InfoViewController *ivControllerCell;
UINavigationController *infoNavController;
}

@end

Откройте реализацию файла и в методе “viewWillAppear” пропишите приведенный ниже код. Это метод всегда вызывается перед появлением представления.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

//Запускаем панель инструментов
toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleDefault;

//Устанавливаем панель по ширине окна приложения.
[toolbar sizeToFit];

//Вычисляем высоту панели
CGFloat toolbarHeight = [toolbar frame].size.height;

//Получаем предельные значения для представления верхнего уровня
CGRect rootViewBounds = self.parentViewController.view.bounds;

//Получаем высоту представления верхнего уровня
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);

//Получаем ширину представления верхнего уровня
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);

//Создаем прямоугольник для панели инструментов
CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);

//Меняем положение и размеры получателя
[toolbar setFrame:rectArea];

//Создаем кнопку
UIBarButtonItem *infoButton = [[UIBarButtonItem alloc]
initWithTitle:@"Info" style:UIBarButtonItemStyleBordered target:self action:@selector(info_clicked:)];

[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];

//Добавляем кнопку как subview к контроллеру навигации.
[self.navigationController.view addSubview:toolbar];

//Перезагружаем табличное представление
[self.tableView reloadData];

}

Первым шагом инициализируем панель инструментов и рассчитаем ряд значений, определяющих ее положение и высоту/ширину. К панели добавляется вновь созданная кнопка, при щелчке по которой вызывается метод “info_cancel”. Кнопка добавляется через LTR, а после — панель к контроллеру навигации как подпредставление.

В редакторе IB добавьте еще одно представление, которое я назвал “InfoView“. В XCode создайте “UIViewController” с именем “InfoViewController” и назначьте этот класс для использования nib-файлом “InfoView“. В “InfoViewController” задекларируйте свойство Boolean с названием “isViewPushed“, которое будет истиной при помещении представления наверх стека и ложью, когда представление будет модальным. Ориентируясь на величину данной переменной, мы добавим кнопку отмены при загрузке представления в качестве модального.

Вот как будет выглядеть при щелчке информационная кнопка:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (void) info_clicked:(id)sender {

//Инициализация Info View Controller
if(ivControllerToolbar == nil)
ivControllerToolbar = [[InfoViewController alloc] initWithNibName:@"InfoView" bundle:[NSBundle mainBundle]];

ivControllerToolbar.isViewPushed = NO;

//Инициализация контроллера навигации контроллером info view controller
if(infoNavController == nil)
infoNavController = [[UINavigationController alloc] initWithRootViewController:ivControllerToolbar];

//Представление контроллера навигации
[self.navigationController presentModalViewController:infoNavController animated:YES];

}

Из заголовочного файла мы знаем, что задекларировано два типа контроллеров “ViewController” для одного nib-файла. Это объясняется тем, что при непредсказуемом поведении результаты одного контроллера представления контролирует одна переменная. При щелчке на информационной кнопке сначала инициализируется “ivControllerToolbar“, потом — “infoNavController” с контроллером представления “ivControllerToolbar“. После представляем “infoNavController” посредством метода “presentModalViewController” из “navigationController“. Если этого не сделать, “infoview” будет загружаться без контроллера навигации, отрезав удобный путь возвращения к “RootViewController“. Обратите внимание, что мы четко сообщаем “infoviewcontroller” о том, что контроллер не помещается в стек. Эта переменная будет использована в относящемся к “InfoViewController” методе “viewDidLoad“.

1
2
3
4
5
6
if(isViewPushed == NO) {

self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:@selector(cancel_Clicked:)] autorelease];
}

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

1
2
3
4
-(void) cancel_Clicked:(id)sender {

[self.navigationController dismissModalViewControllerAnimated:YES];
}

Поскольку это табличное представление, выделив строку, пользователь может вызвать для нее детализацию. Вот как будет выглядеть метод “didSelectRowAtIndexPath“:

1
2
3
4
5
6
7
8
9
10
11
12
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Логика навигации — создаем и помещаем в стек новый контроллер представления

//Инициализация контроллера info view.
if(ivControllerCell == nil)
ivControllerCell = [[InfoViewController alloc] initWithNibName:@"InfoView" bundle:[NSBundle mainBundle]];

ivControllerCell.isViewPushed = YES;

//Помещение контроллера представления наверх стека
[self.navigationController pushViewController:ivControllerCell animated:YES];
}

Сначала инициализируем контроллер info view с названием “ivControllerCell“, с помощью которого загружается тот же контроллер представления в методе “didSelectRowAtIndexPath“. В этот раз сообщим контроллеру info view, что представление будет помещено наверх стека.

Это самый простой из найденных мной способов добавить в приложение с “UINavigationController” элемент “UIToolbar“. Удачи!

Исходный код скачать можно [здесь]

Текст оригинальной статьи на английском языке [здесь]

Уважаемые читатели, данный материал был переведен и подготовлен к публикации проектом LookApp.ru, при публикации на другом сайте ссылка на LookApp.ru обязательна.

1 звезда2 звезд3 звезд4 звезд5 звезд (2 голосов, средний: 3.50 из 5)
Загрузка ... Загрузка ...


One Response to “Уроки iPhone SDK: Контроллер навигации и панель “UIToolbar””

  1. 1. azee Says:

    Спасибо большое за статью - то что нужно для работы, сильно помогла.
    Единственное, нашёл недостаток, это то что нужно для tableview тоже размер нужно задать - у меня последнюю строка в таблица скрыта тулбаром.

Оставьте комментарий