Как использовать storyboards и swapping views

Традиционные nib файлы скрыты под интерфейсом раскадровок и работа с ними продолжается посредством раскадровок. Раскадровки позволяют писать меньше кода, например они уже содержат код для того чтобы сменять вьюхи (swap views). Поэтому этот код не нужно писать.

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

Storyboards - это новый (начиная с Xcode 4.2) подход к построению интерфейсов и приложений. Они доступны только для iOS.



Swapping views - это то что есть только на iOS устройствах и отсутствует на Macs и desktop-style компьютерах. Экран на iOS устройствах может отображать только одно окно в один момент времени. Может быть multiple views (например split view controllers на iPad, или navigation bar–based интерфейс в Settings на iPhone). Но это views, а не windows. С множеством окон как на desktop компьютере вы можете перемещать их по экрану, сворачивать и разворачивать и прочее. Ничего такого не применимо к iOS экрану.

Поэкспериментировать со swapping views можно создав новый проект по Master-Detail Application template.



На рисунке выше table view отображает две строки - по одной для каждого объекта в persistent store. Для того чтобы обработать tap по строке нужно реализовать метод didSelectRowAtIndexPath (часть протокола UITableViewDelegate). В Master-Detail Application template использующем nib файлы это реализовано в MasterViewController.m.

Swapping the View:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if (!self.detailViewController) {
self.detailViewController = [[DetailViewController alloc]
initWithNibName:@”DetailViewController_iPhone” bundle:nil];
}
NSManagedObject *selectedObject = [[self fetchedResultsController]
objectAtIndexPath:indexPath];
self.detailViewController.detailItem = selectedObject;
[self.navigationController pushViewController:self.detailViewController
animated:YES];
} else {
NSManagedObject *selectedObject = [[self fetchedResultsController]
objectAtIndexPath:indexPath];
self.detailViewController.detailItem = selectedObject;
}
}

Этот код:
  • Создает новый view controller. Обычно это наследник UIViewController или UITableViewController. Или view удовлетворяющее протоколу SubstitutableDetailViewController.
  • Помещает созданный view в  split view controller, navigator, или другое место где оно будет отображаться.
  • Очищает неправильные настройки (such as reflecting that a new detail item has been selected), adjust popovers, и прочее.
Navigation view controller обслуживает свой стек из view controllers; в то время как пользователь взаимодействует с navigation view controller, новые view controllers добавляются и и извлекаются из его стека.


На обоих iPhone и iPad интерфейсах detail view делает swapped in. На iPhone, оно заменяет master view в navigation interface, а на iPad, оно заменяет то что сейас отображается в detail view (в самом начале в нем отображаются данные по умолчанию).

Storyboards использовались для планирования time-dependent проектов, таких как Stanislavski’s production of The Seagull (1898), Walt Disney cartoons (“Three Little Pigs” in 1933), Gone with the Wind (1939), и многих других. Фреймы в storyboard обычно представляют одиночную сцену или снимок камеры в клипе. Первоначально каждая сцена была карандашным наброском, но сейчас каждая сцена может быть показана как фото или даже ключевой фрейм из movie clip. Storyboarding становится важным инструментом в разработке игр и ПО.

Storyboards в Xcode принимают модель последовательности сцен, каждая из которых обычно view в смысле UIView или его потомка. Переходы между сценами раскадровки (storyboard) важны в играх и интерактивном ПО, т.к. они предоставляют механизм для смены линейной последовательности обычной раскадровки. Анимация при переходе могут тонко намекать пользователю, что случится дальше (например, приложение ждет пользовательского ввода). В Xcode, переход называется segue, а слово transition обычно используется в музыке и других областях.


На рисунке выше, 3 сцены в раскадровке. Слева направо это: navigation view controller, master view controller, и detail view controller. Имя каждого контроллера указано под view. При клике на имени оно заменяется его placeholder-ами — File’s Owner (now filled in with the name) и First Responder. (Если редактор в малом масштабе, то нужно сделать двойной щелчок).


Между сценами находятся переходы (segues). Настройки отображаются в Attributes inspector.

Обратите внимание что от navigation controller к master view controller, соединение is actually containment, и поэтому тут не segue details в Attributes inspector.

Сцены соединяются путем control dragging от одной к другой. Переход создает автоматически и настраивается в Attributes inspector.

В storyboard для iPad используются те же самые контроллеры что и для iPhone версии. Но переходы отличаются.


Обратите внимание, что соединения на рисунке выше, это только соединения. Тут нет переходов.

Раскадровки содержат ссылки на view controllers и переходы, которые связывают их вместе в раскадровке. В структуре nib-файла контроллеры идентифицируются как классы указанные в placeholder-е File’s Owner в Interface Builder редакторе (класс устанавливается Identity inspector).

В классе UIStoryBoard объявлено всего три метода:

  • storyboardWithName:bundle: - создает и возврщает объект;
  • instantiateInitialViewController - instantiates the initial view controller in the storyboard’s view controller graph;
  • instantiateViewControllerWithIdentifier:.


Теперь снова рассмотри три шага для управления вьюхами:
1) Create the appropriate view controller.
2) Put it in the appropriate place (such as within a split view controller).
3) Clean up and finish by adjusting popovers, toolbars, and the like.

Первые два шага создание соответствующего контроллера и помещение его в надлежащий контроллер может быть сделано раскадровкой используя собственные методы.

Поддержка раскадровок в коде проводится с помощью 3 методов, которые добавляются в UIViewController. Первое это просто свойство, которое возвращает раскадровку содержащую view controller. Для view controllers созданных из nib файлов вместо storyboard файлов свойство возврщает nil значение.

Переход (segue) определяется в раскадровке (storyboard) и инстанцируется в runtime. Метод prepareForSegue вызывается у view controller когда переход должен выполниться.

prepareForSegue в MainViewController.m (iPad):
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@”showDetail”]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *selectedObject = [[self fetchedResultsController]
objectAtIndexPath:indexPath];
[[segue destinationViewController] setDetailItem:selectedObject];
}
}

prepareForSegue зависит от идентификатора перехода showDetail. Это справедливо только для iPhone проектов. На iPad, обе части split view controller представлены всё время, даже если master view controller не показывается. Т.к. оба объекта доступны, то detail item для detail controller может быть установлен напрямую. Код ниже показывает это. Сравните его с кодом выше и вы увидите что они делают одно и то же (set the detail item).

didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
NSManagedObject *selectedObject = [[self fetchedResultsController]
objectAtIndexPath:indexPath];
self.detailViewController.detailItem = selectedObject;
}
}

Проект сам определяет storyboard для каждой среды, но можно настроить:


Можно свободно добавлять(удалять) view контроллеры в(из) раскадровку(и):


На рисунке выше был добавлен split view controller. Это сложны объект который содержит: split view controller, navigation controller, table view controller, и view controller. Маленькая стрелка слева означает что это первый вид в раскадровке.

Если нажать ПКМ на view controller то можно увидеть его segues, outlets, referencing segues, and referencing outlets and outlet collections.


Начальные настройки для split view controller