Статьи

Начало разработки для iOS: создание Fortune Crunch

Добро пожаловать на второй курс из нашей серии руководств для начинающих разработчиков iOS. Из этого туториала Вы узнаете, как создать приложение FortuneCrunch, ранее показанное в нашей статье «Введение в iPhone SDK». В дополнение к видеоформату, эта версия была обновлена ​​для iOS4 и содержит гораздо больше подробностей о различных этапах создания приложения. Зрители могут рассчитывать на знакомство с рабочими процессами Xcode и Interface Builder, как настраивать кнопки и реагировать на события кнопок, а также на основы Objective-C и Cocoa-Touch. Письменная стенограмма также предоставляется с этим постом.

На сегодняшнем уроке мы собираемся создать простое приложение для iOS под названием «FortuneCrunch». Я разработал Fortune Crunch как «Hello World» для программирования на iPhone. Он содержит достаточно подробностей, чтобы вы могли начать понимать рабочий процесс Xcode и Interface Builder, основы синтаксиса Objective-C и как реагировать на действия кнопок.

Давайте начнем с запуска Xcode. Xcode — это запатентованная интегрированная среда разработки Apple, которая включает в себя все инструменты, необходимые для создания собственных приложений для iPhone. Начните с выбора «Создать новый проект XCode».

Теперь у вас есть список различных шаблонов приложений iOS. Каждый шаблон предназначен для различных видов приложений, и вы можете прочитать подробности в описании, которое приводится при нажатии на значок шаблона. Для нашего приложения мы выберем шаблон «View-based Application», так как нам нужен только один экран для этого проекта. Введите имя «FortuneCrunch» и нажмите «Сохранить».

И добро пожаловать в Xcode. Мы рассмотрим Xcode более полно в следующем уроке, но сейчас я просто хочу, чтобы вы ознакомились с тремя основными представленными областями контента. Панель «Группы и файлы» — это список всех файлов в вашем проекте. Если вы выберете папку, вы увидите все файлы в ней, показанные справа, и, наконец, выбор отдельного файла отобразит содержимое на панели ниже. Это также ваш редактор кода, который вы можете увеличить, перетащив панель вверх или вниз или дважды щелкнув файл, чтобы открыть его в новом окне.

Хорошо, это все довольно интуитивно понятно. Давайте подробнее рассмотрим панель «Группы и файлы». Папка «Классы» — это место, где будут храниться почти все исходные файлы в ваших приложениях. Как вы уже догадались, это означает, что в Objective-C вы, естественно, почти всегда редактируете файлы классов, потому что практически все в вашем приложении является объектом.

По умолчанию в папке «Другие источники» содержатся два очень полезных файла: FortuneCrunch_Prefix.pch и main.m. Основная функция в main.m вызывается операционной системой iOS и является первым кодом, который будет выполнен в вашем приложении. Несмотря на то, что вы будете редко его использовать, для выполнения пользовательского кода это нулевая точка. FortuneCrunch_Prefix.pch — это хороший способ уменьшить вероятность развития синдрома carpel-tunnel, то есть он позволяет автоматически импортировать код из различных библиотек или заголовочных файлов во все исходные файлы вашего проекта. Папка ресурсов обычно используется для организации всех ваших файлов XIB, файлов plist, изображений, аудио и видео. Папка Frameworks отображает все доступные в настоящее время рамки для вашего проекта, а папка products отображает двоичный файл приложения. Обратите внимание, что в данный момент он красный, что означает, что он отсутствует, потому что мы еще не создали двоичный файл.

Давайте решим эту проблему сейчас. Убедитесь, что ваше здание для симулятора, а не физического устройства, а затем идите дальше и нажмите значок «Построить и запустить», чтобы начать процесс компиляции.

Добро пожаловать в симулятор iPhone. Как видите, это наш шаблон проекта по умолчанию в действии. Довольно скучно, не правда ли? Мы исправим это дальше.

Вернитесь к Xcode и найдите XIB-файл FortuneCrunchViewController. XIB содержит информацию об интерфейсе вашего представления и, следовательно, обычно управляется Interface Builder. Дважды щелкните, чтобы открыть файл в Интерфейсном Разработчике сейчас.

Глядя на середину экрана, это окно должно выглядеть особенно знакомым. Это визуальное представление представления, управляемого классом FortuneCrunchViewController, и мы только что увидели его, когда скомпилировали наш проект по умолчанию. При работе в Интерфейсном Разработчике мне нравится думать об этом окне как о «Холсте». Однако, в отличие от холста художника, мы не можем рисовать вид непосредственно, мы можем только размещать объекты сверху. Вот для чего окно библиотеки. Идите вперед и сканируйте различные объекты, перечисленные здесь, и давайте даже немного поэкспериментируем. Мы могли бы разместить табличное представление на холсте или, возможно, изображение, с текстовым представлением внизу. Но для наших целей мы будем использовать кнопку. И не просто кнопка, а класс под названием «UIButton». Перетащите кнопку на экран сейчас. Что касается кнопок по умолчанию, то, к сожалению, эта эстетически не может стать намного хуже. Убедитесь, что кнопка выбрана, а затем взгляните на окно инспектора. В окне «Инспектор» отображаются различные параметры для настройки объектов в вашем представлении, и эти параметры буквально представляют собой визуальное представление свойств вашего объекта, также называемых элементами данных. Вы заметите, что одним из первых вариантов UIButton является свойство «Тип». Давайте поиграем с этим, чтобы увидеть различные варианты.

У нас есть «Подробное раскрытие», «Инфо-свет», «Инфо-темнота», «Добавить контакт» и наш выбор по выбору в этом уроке. Пользовательская кнопка позволяет установить изображения для всех доступных состояний кнопки, включая состояние по умолчанию, выделенное состояние, выбранное состояние и отключенное состояние.

В этом руководстве мы будем использовать UIButton для отображения файла cookie состояния с состоянием по умолчанию. Чтобы продолжить, нам нужно импортировать наши изображения.

Чтобы получить изображения FortuneCrunch, предоставленные в этом руководстве, вам необходимо скачать код проекта FortuneCrunch, прикрепленный к этому сообщению. После загрузки и разархивирования кода откройте папку FortuneCrunch, и вы увидите два изображения, которые нам понадобятся в вашем приложении: -cookie-closed точка-пинг и cookie-хрустированный пункт-пинг. Выберите оба этих изображения, а затем перетащите их в папку ресурсов в XCode. Обратите особое внимание на это диалоговое окно, в верхней части которого есть опция «Копировать элементы в папку группы назначения», которую вам необходимо проверить. Как вы уже догадались, это говорит XCode, что вы действительно хотите копировать и импортировать изображения в XCode вместо того, чтобы просто ссылаться на файлы. Нажмите «Добавить», и теперь у вас должны быть файлы cookie закрыты и файлы cookie в вашем проекте. Прежде чем продолжить, оглянемся на папку FortuneCrunch. Вы также хотите перетащить в файл «Icon.png». По умолчанию любое изображение под названием «Icon.png» станет значком приложения, отображаемым iOS. Обратите внимание, что наш icon.png не имеет никакого примененного блеска — это автоматически применяется iOS.

Теперь вернитесь к Интерфейсному Разработчику. Выберите объект UIButton и измените изображение для состояния по умолчанию на cookie-crunched.png. Затем выберите Layout -> Size to Fit. Переместите кнопку так, как вы хотите, чтобы она отображалась. Теперь мы собираемся добавить UILabel на холст, чтобы представить наше состояние. Для моего приложения я собираюсь добавить текст «Счастливого взлома iPhone!» Настройте текст с помощью опции шрифта окна инспектора. Я собираюсь изменить свой шрифт на 12pt с жирным шрифтом. Следует отметить одну вещь, которая касается шрифтов: все шрифты в вашей системе будут представлены, но большинство из них по умолчанию недоступны в iOS, поэтому будьте осторожны при выборе стиля шрифта. Измените ширину метки с помощью параметра «Макет -> Размер по размеру», а затем перетащите ее в нужное место на бумаге состояния. Я также собираюсь изменить цвет текста с черного на красный. Наконец, установите для свойства «hidden» значение true, поскольку мы хотим, чтобы этот ярлык появлялся только после того, как пользователь коснулся изображения cookie.

На самом деле мы устанавливаем только состояние по умолчанию для нашего UIButton на crunched, чтобы мы могли правильно расположить метку. После этого мы хотим, чтобы состоянием по умолчанию для нашей кнопки было закрытое изображение. Тем не менее, как выделенное состояние, так и выбранное состояние будет сжатым файлом cookie. Как вы можете видеть, Interface Builder не будет отражать свойства, установленные для этих состояний; вам придется протестировать их с помощью кода и симулятора iPhone.

Наше изображение с закрытыми файлами cookie имеет белый фон, а фон просмотра — серый. Измените фон просмотра на белый, чтобы соответствовать изображениям cookie. Там намного лучше.

Теперь продолжайте и сохраните свою работу в Интерфейсном Разработчике, а затем переключитесь обратно на Xcode. «Построить и запустить» приложение снова в XCode, чтобы посмотреть на ваш прогресс.

Не совсем то, что вы ожидали, верно? С появлением iOS 4 приложения поддерживают многозадачность по умолчанию. Поэтому, когда мы нажимали кнопку «Домой» перед закрытием приложения, мы фактически не останавливали процесс, мы просто отправляли его в фоновый режим. Один из способов обойти этот факт — дважды щелкнуть кнопку «Домой», удерживать курсор над значком нашего приложения и затем вручную завершить процесс приложения. Однако лучший способ — использовать «Build and Debug» вместо «Build and Run» при активной разработке вашего приложения. И теперь вы можете увидеть наши изменения.

Прежде чем мы перейдем к написанию кода нашего приложения, я дам вам совет по поводу файлов Interface Builder. Даже если вы почти всегда будете редактировать файлы XIB с помощью Interface Builder, файл XIB на самом деле представляет собой просто файл XML, который содержит метаданные об объектах, которые будут созданы автоматически при создании экземпляра контроллера представления. Это можно увидеть, нажав команду FortuneCrunchViewController.xib и выбрав «Открыть как -> Файл исходного кода». Если вы используете систему контроля версий, такую ​​как SVN, CVS или GIT, вы, вероятно, также заметите это при рассмотрении различий между проверками.

Теперь перейдем к программированию нашего приложения. Взгляните на FortuneCrunchViewController.h и FortuneCrunchViewController.m. Эти два файла вместе составляют объект контроллера представления, который будет управлять единственным представлением в нашем приложении. Файл .h называется объявлением класса, или интерфейсным файлом, или даже просто файлом «заголовка». Файл .m называется либо определением класса, либо файлом реализации. Файл объявления класса используется для описания того, что представляет собой наш класс, тогда как файл определения класса используется для описания того, как на самом деле работает наш класс.

Конечно, сами по себе оба являются просто текстовыми файлами. Это то, что внутри, что имеет значение. Удалить все, что в данный момент существует в файле интерфейса; мы собираемся начать с нуля.

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

Хорошо, но Objective-C также поддерживает другой стиль комментариев:

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

Следующая строка — это оператор импорта. #import — это директива препроцессора, которая делает любой указанный файл или структуру доступными для нашего класса. Это как если бы вы ввели содержимое этого файла или фреймворка прямо в этот момент в исходном файле. Поскольку мы воспроизводим исходный файл определения класса, мы скажем #import <UIKit/UIKit.h> чтобы добавить инфраструктуру UIKit. Эта структура содержит множество классов, которые мы будем использовать, которые являются уникальными для iOS, такие как UIButton, UIImage, UIViewController и т. Д.

Наш следующий шаг — объявить, что этот файл является файлом объявления класса с оператором @interface . Как вы можете видеть из функции автозаполнения, синтаксис объявления интерфейса класса: @interface, имя класса, двоеточие, имя суперкласса, открывающая фигурная скобка, внутренние переменные или ивары, иногда называемые членами данных, закрывающая фигурная скобка с последующим методом декларации, а затем оператор @end .

Мы назовем наш класс FortuneCrunchViewController и перечислим суперкласс как UIViewController, поскольку мы хотим наследовать все функциональные возможности от стандартного ViewController и просто настроить части, уникальные для нашего представления. Нам понадобятся два ивара в нашем классе, один для UIButton с нашим изображением cookie, и один для UILabel который содержит наш текст cookie состояния. Объявите эти переменные следующим образом:

Все, что действительно нужно для того, чтобы объявить ivar, это имя класса, звездочка, синтаксис имени переменной. Ключевое слово IBOutlet обозначает выход Interface Builder и используется в качестве тега, который позволит нам устанавливать соединения с этой переменной непосредственно в Interface Builder.

Теперь мы объявим, что хотим, чтобы обе вышеуказанные переменные считались свойствами класса. Сделайте это со следующими строками:

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

Основной синтаксис для объявлений методов в Objective-C — это знак плюс или минус, тип возвращаемого значения и имя метода. В нашем случае мы будем использовать минус, потому что это метод экземпляра. Если бы мы хотели, чтобы этот метод был частью класса, мы использовали бы знак плюс, чтобы создать метод класса. Далее мы указываем наш тип возвращаемого значения как IBAction, который на самом деле является синонимом void, с той лишь разницей, что IBActions, или действия Interface Builder, можно манипулировать в Interface Builder.

Другие возможные возвращаемые типы включают в себя примитивные типы, такие как int, char и float, или классы, такие как NSString, UIImage и NSNumber. Соответственно, мы называем наш класс «crunchCookie», потому что это именно то, что он будет делать.

Наконец, нам нужно добавить оператор @end под наш метод, чтобы завершить нашу декларацию @interface .

Теперь сохраните вашу работу в Xcode и переключитесь обратно на Interface Builder.

Объявив метку и кнопку в Xcode, нам нужно синхронизировать объекты, которые мы поместили в представление в IB, с объектами в нашем файле декларации.

Посмотрите на объект владельца файла в окне содержимого XIB. Если вы посмотрите на инспектор для этого объекта, вы заметите, что Владелец Файла на самом деле является экземпляром FortuneCrunchViewController.h. Это представление объявления класса, которое мы только что редактировали, и если вы щелкните правой кнопкой мыши, вы заметите, что наши переменные IBOutlet перечислены в разделе торговых точек. Теперь мы можем подключить нашу кнопку и наш ярлык.

Нам также нужно подключить действие нашей кнопки к методу, который мы объявили. Выберите кнопку на холсте и щелкните правой кнопкой мыши. Вы увидите этот длинный список событий кнопок. Двумя наиболее распространенными являются подправить внутрь и приземлиться. Касание внутри срабатывает, когда пользователь нажимает на кнопку, а затем отпускает кнопку, оставляя палец внутри границ кнопки. Таким образом, событие не сработает, пока пользователь фактически не уберет палец с кнопки. В нашем случае мы хотим, чтобы изображение изменилось как можно скорее, поэтому мы хотим использовать событие касания, которое будет срабатывать, как только на кнопке будет обнаружено касание. Перетащите курсор от круга до объекта «Владелец файла», чтобы выполнить синхронизацию с нашим методом crunchCookie.

Вот и все. Теперь у нас есть синхронизированные IBOutlets и IBAction с объектами в нашем файле XIB. Сохраните свою работу и переключитесь обратно на Xcode.

Мы наконец готовы начать кодирование нашего файла определения класса. Откройте FortuneCrunchViewController.m. Как и раньше, удалите все, чтобы мы могли начать с нуля.

Мы начнем файл с некоторых стандартных шаблонных комментариев:

Первое, что мы хотим сделать, это импортировать файл объявления или заголовочный файл, который мы кодировали ранее. Сделайте это с помощью оператора import:

Вы можете быть удивлены, почему мы должны импортировать файл заголовка здесь. Почему бы просто не ввести его напрямую и сохранить все в одном файле? Фактически, вы могли бы сделать это, но, как правило, объявления классов и определения классов обычно хранятся в двух отдельных файлах.

Далее нам нужно объявить нашу реализацию. Это делается с @implementation оператора @implementation :

Это довольно просто. Я также добавлю команду, чтобы завершить нашу реализацию, поэтому я не забуду сделать это позже:

В нашем файле объявлений мы указали, что хотим, чтобы и fortuneLabel, и cookieButton были свойствами этого класса. Мы собираемся закончить работу сейчас, синтезируя эти свойства, вот так:

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

Теперь давайте перейдем к добавлению фактического метода crunchCookie:

Вот и все. В строках 3-4 мы вызываем метод setImage: forState объекта cookieButton и передаем новый UIImage и константу UIControlStateNormal. Возможно, это выглядит довольно чуждо, если вы работаете с другим языком программирования. Не беспокойтесь о синтаксисе этого урока, все будет раскрыто в будущем. Следующая строка более проста: мы меняем значение свойства «hidden» объекта fortuneLabel. Помните флажок «скрытый» в Интерфейсном Разработчике? Это установило для этого свойства значение true и скрыло метку. Мы изменим это, установив здесь значение FALSE, чтобы наш текст состояния отображался при разрушении файла cookie.

Мы почти готовы построить и отладить наши изменения, но есть еще несколько методов, которые мы должны добавить сначала:

Это унаследованные методы из класса UIViewController, которые имеют дело с управлением памятью. Метод viewDidUnload вызывается, когда на устройстве недостаточно памяти и ему необходимо освободить неиспользуемые представления. В этом сценарии вам необходимо освободить любые связанные с представлением объекты, которые будут перезагружены при повторном создании представления. Эти элементы обычно помечаются ключевым словом IBOutlet, а в нашем случае это объекты fortuneLabel и cookieButton. Отпустите их так:

Метод dealloc вызывается, когда фактический объект FortuneCrunchViewController собирается освободить или удалить из памяти. Вы также захотите выпустить те же объекты здесь:

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

Хорошо, готов увидеть плоды своего тяжелого труда? Сохраните файл и нажмите «Построить и отладить». Когда вы нажмете кнопку cookie, вы увидите, как раскрывается ваше состояние.

Поздравляем с завершением второго урока из нашей серии по разработке под iOS. Разработка для iPhone с Objective-C имеет сложную кривую обучения, но, надеюсь, что после завершения этого урока вам будет удобнее работать с Xcode и Interface Builder, и вы начнете понимать некоторые основы разработки приложений с Cocoa-Touch. Если у вас есть какие-либо вопросы, не стесняйтесь оставлять их в разделе комментариев ниже или связываться со мной напрямую через Twitter: @markhammonds. До следующего раза, Happy iPhone Hacking.