Статьи

iOS 5 SDK: раскадровки

Раскадровка – одна из самых захватывающих новых функций в iOS 5 SDK. Взгляните на множество функциональных возможностей, предлагаемых раскадровками в сегодняшнем руководстве по iOS 5 SDK!

IOS 5 SDK поставляется с множеством новых API для игры. iCloud – это отличный новый интерфейс, который разработчики могут использовать для того, чтобы их приложения создавали максимально удобное взаимодействие с пользователем. ARC представляет собой фундаментальный сдвиг в управлении памятью во всех ваших приложениях. Но, пожалуй, самым разрушительным дополнением к поясу инструментов для разработчиков iOS 5 является Storyboarding. Раскадровка большая. Это изменит способ написания большей части кода вашего интерфейса, а также предоставит возможность повлиять на ваш рабочий процесс разработки в целом в команде. Является ли раскадровка подходящим API для вашего следующего приложения? Если вы хотите обновить существующие приложения, чтобы использовать его? Давайте еще немного углубимся в этот новый API и посмотрим, что он может предложить.


По сути, раскадровки – это новый тип контейнера, доступный в Xcode для хранения коллекций NIB / XIB. В результате вам, возможно, никогда не понадобится снова использовать только независимый файл * .XIB (не паникуйте – они все равно будут вести себя точно так же, как и раньше, если вам нужно продолжать использовать их сейчас). Файл Storyboard не только будет содержать коллекцию NIB, но также позволит вам визуально контролировать, как эти представления будут переходить друг от друга. Это означает, что весь поток интерфейса вашего приложения можно смоделировать и визуализировать с помощью одного файла раскадровки. Как правило, поток интерфейса требует возможности получать экземпляры контроллеров, к которым вы хотите передавать, отправлять данные в эти экземпляры, а затем фактически отображать эти экземпляры с некоторым типом перехода или перехода. Это все очень просто сделать с помощью раскадровки, и использование раскадровок вместо файлов XIB позволит вам вырезать много кода из ваших проектов. Но раскадровка на этом не заканчивается. Раскадровка также позволяет с легкостью создавать ячейки табличного представления и контроллеры табличного представления. Давайте посмотрим, как UIStoryboarding конкретно обращается к каждому из этих вариантов использования.


Важным соображением перед принятием решения об использовании раскадровки является управление версиями. Проект, созданный с использованием Storyboarding, будет совместим с iOS 5 и выше. Хотя вы могли бы создать приложение с раскадровкой и создать надлежащие проверки для использования других iOS 4 или ранее дружественных XIB в определенных местах, это было бы большой дополнительной работой за небольшую отдачу. Если вам потребуется поддержка выпусков до iOS 5, вам, вероятно, следует использовать стандартный контроллер представления и метод разработки пользовательского интерфейса XIB.


Есть образец проекта, сопровождающий эту статью. Вы можете получить его на GitHub .


Все способности UIStoryboards так или иначе связаны между собой, поэтому трудно выбрать логическую точку входа для описания объектов. Мы начнем с рассмотрения нового интерфейса макета раскадровки и продолжим работу. Ниже вы увидите пример окна редактора UIStoryboard в Xcode 4.2:

UIStoryboard Editor View Zoomed Out

Здесь вы можете ясно видеть, что у меня есть 6 различных контроллеров представления, представленных во всем потоке приложения. Для соответствия официальной номенклатуре Apple мы будем называть каждый из разделов раскадровки «сценой». Некоторые сцены будут иметь * .h и * .m представления файлов контроллера, а некоторые полностью настроены в Интерфейсном Разработчике. В демонстрационном проекте я представляю начальную сцену, которая приводит к 5 отчетливо различным сценам. У меня есть только 3 явно определенных подкласса UIViewController, чтобы охватить все 6 сцен. Весь этот поток движущихся сцен на экране и за его пределами может быть составлен из этого вида компоновки раскадровки. На рисунке выше показан увеличенный вид раскадровки. Здесь вы не можете перемещать определенные элементы UIKit в представлениях, а скорее вы должны организовать высокоуровневый поток ваших сцен. Как только вы закончите, вы можете увеличить масштаб и начать указывать детали каждой сцены.

UIStoryboard Editor View Zoomed In

Контроллеры представлений, особенно контроллеры табличных представлений, теперь могут быть явно определены исключительно через раскадровку. Отныне, если вы просматриваете контроллер или контроллер табличного представления, содержащий только статическое содержимое, вы можете реализовать все это с помощью редактора раскадровки. Панели инспектора Интерфейсного Разработчика были обновлены всем необходимым для определения статического табличного представления и проектирования ячеек табличного представления. Ниже вы можете увидеть увеличенное изображение параметров для настройки этих статических таблиц и ячеек через Interface Builder.

UIStoryboard Static Table View Configuration
UIStoryboard Static Table View Cell Configuration

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

Sample Application Static Table View

Чтобы упростить это, вся информация об источниках данных, которую мы так хорошо знакомы с предоставлением табличных представлений, теперь визуализируется через представление иерархии объектов в Интерфейсном Разработчике. Это будет представлять все ваши таблицы разделов, ячеек и так далее. Следя за этим, вы поймете, как выполняемые вами действия WYSIWYG преобразуются в более традиционные вводы данных для табличных представлений.

Sample Application Static Table Interface Builder Object Hierarchy View

Итак, как вы можете видеть, здесь много нового! Многие приложения имеют не динамические табличные представления, которые ранее были реализованы с использованием отдельных UITableViewControllers, но теперь вы можете делать их все визуально. Помните, что меньше кода обычно означает меньше ошибок. Здесь есть еще много интересных вещей со статическими представлениями таблиц, но у нас еще много интересного, поэтому давайте двигаться дальше.


Конечно, вы можете использовать классические методы протокола UITableViewDataSource для программного определения содержимого табличных представлений. Это по-прежнему, вероятно, потребуется для большинства ваших табличных представлений. Тем не менее, раскадровки также предлагают некоторую помощь здесь. Интерфейсный Разработчик теперь имеет намного большую поддержку для определения пользовательских UITableViewCells визуально. Когда вы делаете это, вы размещаете элементы пользовательского интерфейса в ячейке так, как вы себе это представляете, и последний шаг – предоставить ячейке табличного представления reuseIdentifier.

Dynamic Table View Cell Definition

После этого вы можете получить экземпляр ячейки табличного представления, используя следующую для вашего tableView: cellForRowAtIndexPath: метод источника данных:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @”dyncamicCell”;
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 
    if (cell == nil) {
 
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
 
    cell.textLabel.text = [NSString stringWithFormat:@”Section: %d Row: %d Sum: %d Product: %d”, indexPath.section, indexPath.row, (indexPath.section+indexPath.row), (indexPath.section*indexPath.row)];
 
    return cell;
}

Итак, помимо всех этих красивых статических и динамических контроллеров представления, вы можете видеть, что у меня есть стрелки, соединяющие все сцены вместе. Это вторая важная часть в раскадровке. Эти стрелки являются новыми объектами UIStoryboardSegue. Они представляют собой такие вещи, как вставка контроллеров представления в контроллер навигации, модальное представление представлений и любой другой вид пользовательского перехода, который вы можете придумать. Segues так же легко реализовать, как перетаскивание соединения между двумя сценами. Любая кнопка или Gesture Recognizer (который, кстати, теперь также настраивается для представлений в IB, здесь есть масса новых вещей!) Может иметь «push», «модальное» или «пользовательское» segue-соединение, указанное в раскадровке. Все это очень просто настроить с помощью редактора раскадровки, и вы получите конечный результат, который выглядит примерно так:

Hooking up a table view cell to a call a modal segue
Segue after it gets hooked up

Таким образом, все это может быть выполнено без написания кода. Интересный случай использования появляется с модальным представлением сцен. Когда это происходит, вам по умолчанию не предоставляется кнопка возврата контроллера навигации, поэтому вам потребуется регулярный IBAction для вызова, когда сцена должна быть закрыта. Но в случае модального представления сцен через раскадровку вы делаете следующее:

1
2
3
– (IBAction)done:(id)sender {
    [self dismissModalViewControllerAnimated:YES];
}

Несмотря на введение свойства представляющего ViewController в UIViewControllers в iOS 5, при отклонении модальных представлений, представленных раскадровкой, вы вызываете dismissModalViewControllerAnimated: в модально представленном контроллере представления, а не в его parentViewController или presentingViewController.

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

1
-(void)perform;

Я сделал простой пример постепенного перехода с примером проекта, упомянутым выше. Это несколько уникальный класс для подкласса. Из документации Apple, ваши обязанности, если вы решите сделать это:

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

Вы, вероятно, использовали бы здесь некоторую базовую анимацию, и, без сомнения, мы увидим некоторые интересные подклассы UIStoryboardSegue с открытым исходным кодом. Я использую простой вспомогательный метод UIView для выполнения перехода и по завершении помещаю новый контроллер представления на контроллер навигации без анимации. Вы можете увидеть код для метода execute ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
-(void)perform {
 
    __block UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
    __block UIViewController *destinationController = (UIViewController*)[self destinationViewController];
 
    [UIView transitionWithView:sourceViewController.navigationController.view
                      duration:.5
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        [sourceViewController.navigationController pushViewController:destinationController
                                                                             animated:NO];
                    }
                    completion:^(BOOL finished) {
                        NSLog(@”Transition Completed”);
                    }];
}

Segues также важны для передачи данных между этими представлениями. При представлении представления у контроллера представления будет метод:

1
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

называется. Это ваша возможность отправить данные в следующее представление. В UIStoryboard segue, поставляемом в сигнатуре метода выше, есть свойство destinationViewController, в которое вы можете передавать данные. Хотя это охватывает концепцию передачи данных контроллеру представления, передача данных обратно немного сложнее. Apple применяет модель протокола. Это должно быть сделано в коде, где вы определяете протокол в самом верхнем контроллере представления и имеете контроллер представления, который передает данные обратно для его реализации. Это один из вариантов использования передачи данных, который не был рассмотрен этими усовершенствованиями в редакторе IB, поэтому вам нужно будет создать этот протокол вручную.


Я занимался разработкой для iPhone еще до того, как SDK даже поддерживал Interface Builder. Мы говорим о самом первом выпуске. И по сей день, в Xcode 4.1 и более ранних версиях, меня иногда смущало, какой XIB должен был содержать мой Navigation Controller и как я его точно настроил. Похоже, что Apple уже слышала крики разработчиков по этому поводу, потому что теперь появилась новая красивая опция для включения контроллеров представления в IB в Navigation Controller и Control Panel Controllers. Новая опция доступна в Редакторе -> Встроить -> Контроллер навигации. Вы можете увидеть изображение варианта ниже. Когда у вас выбран контроллер представления и выбран один из этих параметров, Interface Builder выполнит за вас работу по созданию соответствующего удерживающего контейнера и внедрению его с помощью встроенного контроллера представления. Это одна из моих любимых новых функций в IDE, потому что она представляет Apple, которая действительно начинает адаптировать Xcode для iOS.

Menu to Embed View Controller In Navigation Controller and Tab Bar Controller

Окончательный возможный эффект, который Storyboarding может оказать в ближайшие годы при разработке приложений для iOS на основе команды, зависит от того, как вы можете создавать компоненты. Apple показала примеры доставки статических библиотек (.a-файлов) от других команд и возможности извлекать целые разделы приложения из этих нескольких очень модульных файлов. Показанный шаблон включает в себя пакет, содержащий скомпилированную статическую библиотеку, файл заголовка контроллера базового представления и файл .storyboard. С помощью этих компонентов вы можете теперь создать новую UIStoryboard из их файла раскадровки, передать данные в открытый контроллер базового представления и затем представить его. Библиотека, поставленная другой командой, может иметь столько контроллеров представления, взаимодействий веб-служб или любых других функциональных компонентов, но команде, использующей этот код, придется иметь дело только с 3 элементами. С этим подходом, продвигаемым Apple, я не удивлюсь, если в Xcode появятся новые разработки, поддерживающие этот тип рабочего процесса. Если вы собираетесь работать над большим современным приложением с распределенной командой, это может быть полезно!