Статьи

Dive Into Interface Builder

Несколько недель назад Энди Уайт кратко рассказал нам о Xcode и рассказал о разработке простого приложения «Hello, World» для iPhone.

В этом учебном пособии мы будем опираться на эти уроки и познакомим вас с Интерфейсным Разработчиком, компаньоном XCode, разработанным, чтобы позволить вам быстро и легко разрабатывать интерфейсы для ваших приложений. В процессе мы создадим простое приложение для iPad: большой старый калькулятор, который мы назовем GrandeCalc HD.

Создание проекта

Создание проекта начинается с запуска XCode и использования меню «Файл» для создания нового проекта.

Для этого приложения мы хотим создать приложение на основе View. Обязательно выберите iPad, потому что по умолчанию это устройство iPhone. Не волнуйтесь, ваш проект создаст код, совместимый с обоими устройствами — этот выбор означает, что вы будете использовать макет iPad по умолчанию для Interface Builder.

В следующем разделе мастера проекта вас попросят назвать проект. Я назвал мой GrandeCalc HD и дал ему пространство имен com.jherrington.calculatorhd. Вы можете называть свои как угодно.

Когда проект будет создан, вы увидите что-то вроде этого:

Здесь показаны два основных класса Objective-C, которые управляют приложением. Класс Objective C имеет два компонента, первый — определение интерфейса класса (включая такие вещи, как переменные-члены, свойства и открытые методы); это в заголовочном файле .h . Другой — реализация класса в файле .m .

Первый из ваших двух классов — делегат приложения. Это класс, который обрабатывает ориентированные на приложения события, такие как запуск, завершение работы и т. Д. Мы вообще не будем касаться этого класса. Другой контроллер представления. Это класс, который подключается к элементам интерфейса в представлении и отвечает на нажатие пользователем. Мы добавим туда код Objective-C.

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

Область отображения представления определяется в файле .xib . Это файл построителя интерфейса, который содержит локализованные (в данном случае только английские) версии интерфейса. Этот файл включает в себя все элементы управления, их макет и размеры, их текст, теги, соединения с соответствующими классами Objective-C и так далее.

Мы начинаем редактировать этот файл, дважды щелкнув по нему.

Построение интерфейса

Двойной щелчок по файлу .xib вызовет Interface Builder. Оказавшись там, вы увидите три окна. Одним из них является большое окно, содержащее содержимое представления; второе меньшее окно имеет набор элементов пользовательского интерфейса, которые вы видите ниже.

Здесь мы будем брать текстовый дисплей и кнопки для нашего калькулятора.

Третье окно показывает содержимое файла .xib как показано здесь.

Это окно станет важным, когда мы свяжем кнопки и метку с классом Objective-C, который выполняет всю работу. В этом случае объект First Responder фактически представляет класс Objective-C, который будет обрабатывать все события.

Следующим шагом является перетаскивание некоторых кнопок и UITextField на представление, а затем начать их редактирование. Вы можете раскладывать и стилизовать свои кнопки так, как вам нравится; единственная ключевая точка — установить значение тега каждой цифровой кнопки на числовое значение кнопки. Таким образом, мы сможем использовать один и тот же обработчик событий для каждой кнопки, используя значение тега в нашем коде в качестве соответствующего числового значения. Вот как установить значение тега для кнопки с цифрой 6, например:

Макет, который я придумал, выглядел так:

Не волнуйтесь, если ваш выглядит немного иначе. Пока все соответствующие кнопки и метка на месте, мы сможем подключить их и превратить в функциональный калькулятор.

Есть еще один последний шаг, о котором нужно позаботиться, прежде чем мы перейдем к разработке логики нашего приложения: мы хотим, чтобы наш интерфейс корректно обрабатывал изменения ориентации устройства (из портретной в альбомную или наоборот). Вы можете смоделировать внешний вид интерфейса вашего приложения, выбрав Simulate Interface в меню File. После запуска симулятора попробуйте повернуть имитированный iPad влево и вправо с помощью Cmd-left или Cmd-right. Упс! Наш интерфейс не очень хорошо справляется с ландшафтным режимом. Давайте посмотрим, что мы можем сделать с этим. Каждый элемент в макете имеет набор параметров, которые определяют, как он будет реагировать на изменения ориентации устройства. Выберите одну из ваших кнопок, затем выберите значок линейки в верхней части окна свойств. Вы хотите изменить свои настройки так:

Важный раздел — Авторазмер. Это определяет, как элемент меняет форму и положение во время изменения макета интерфейса. Линии вдоль края поля определяют, является ли положение элемента фиксированным или плавающим относительно каждого края экрана. Элементы управления внутри блока определяют, будет ли элемент изменять высоту или ширину при изменении макета. Для кнопок и отображения текста укажите, что они плавающие и что они изменяют ширину и высоту. Чтобы сделать это, убедитесь, что обе стрелки внутри рамки имеют сплошной красный цвет, а линии за пределами рамки пунктирные. После этого протестируйте интерфейс еще раз: он должен прекрасно выглядеть как в портретном, так и в ландшафтном режимах.

Когда макет пользовательского интерфейса готов, пришло время вернуться к Xcode для работы на Objective-C.

Логика

Классы представления Objective C имеют два критических элемента; IBAction s и IBOutlet s. IBAction — это метод, который реагирует на событие (например, нажатие кнопки). IBOutlet — это свойство, которое класс использует для подключения к элементу пользовательского интерфейса (например, метке числа в калькуляторе). Если вы хотите прослушивать события, вам нужно добавить IBAction s. Если вы хотите изменить состояние интерфейса или прочитать его текущее состояние, вам понадобится IBOutlet s.

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

 #import @interface GrandeCalc_HDViewController : UIViewController { IBOutlet UITextField* numberDisplay; float heldValue; int lastOpDirection; } @property (nonatomic, retain) UITextField* numberDisplay; -(IBAction)numberClicked:(id)sender; -(IBAction)dotClicked:(id)sender; -(IBAction)plusClicked:(id)sender; -(IBAction)minusClicked:(id)sender; -(IBAction)equalsClicked:(id)sender; @end 

Единственным выходом является поле numberDisplay , которое связано с отображением числа в представлении. Затем есть пять действий; они соответствуют соответственно нажатой цифре и нажатию кнопок «точка», «плюс», «минус» и «равно». В каждом случае передается объект sender . Этот sender является элементом пользовательского интерфейса, который сгенерировал событие. Например, это может быть цифровая кнопка, которая была нажата.

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

Если вы новичок в Objective-C, вы должны заметить, что переменные-члены (такие как numberDisplay , heldValue и lastOpDirection ) определены в блоке @interface . Свойства и методы определяются после этого. В этом случае есть одно свойство numberDisplay и пять открытых методов. Свойство numberDisplay будет использоваться интерфейсом для установки и получения указателя объекта на элемент отображения номера в пользовательском интерфейсе.

Реализация для представления, которое содержится в файле .m , показана ниже:

 #import "GrandeCalc_HDViewController.h" @implementation GrandeCalc_HDViewController @synthesize numberDisplay; - (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation { return YES; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (void)dealloc { [super dealloc]; } -(IBAction)numberClicked:(id)sender { UIButton *buttonPressed = (UIButton *)sender; int val = buttonPressed.tag; if ( [numberDisplay.text compare:@"0"] == 0 ) { numberDisplay.text = [NSString stringWithFormat:@"%d", val ]; } else { numberDisplay.text = [NSString stringWithFormat:@"%@%d", numberDisplay.text, val ]; } } -(IBAction)dotClicked:(id)sender { numberDisplay.text = [NSString stringWithFormat:@"%@.", numberDisplay.text ]; } -(IBAction)plusClicked:(id)sender { float curValue = [numberDisplay.text floatValue]; numberDisplay.text = [NSString stringWithString:@"0" ]; heldValue = curValue; lastOpDirection = 1; } -(IBAction)minusClicked:(id)sender { float curValue = [numberDisplay.text floatValue]; numberDisplay.text = [NSString stringWithString:@"0" ]; heldValue = curValue; lastOpDirection = -1; } -(IBAction)equalsClicked:(id)sender { float newValue = heldValue + ( [numberDisplay.text floatValue] * lastOpDirection ); numberDisplay.text = [NSString stringWithFormat:@"%g", newValue ]; heldValue = 0.0f; lastOpDirection = 0; } @end 

Опять же, если вы новичок в Objective-C, ко всему этому потребуется некоторое привыкание, но даже если синтаксис немного странный, вы сможете увидеть некоторые объектно-ориентированные шаблоны, знакомые Java и C ++.

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

В каждом методе вы найдете код Objective-C для реализации метода. В этом коде вы найдете базовые операции C, с которыми вы, вероятно, знакомы; например, арифметические операторы и способ определения переменных. Действительно уникальная часть в объектно-ориентированном синтаксисе вызовов Objective-C.

Давайте посмотрим:

 [NSString stringWithString:@"0" ] 

Это означает создание новой строки со значением «0». Символ @ указывает, что нам нужна строка Objective-C, а не строка C. И в этом случае мы вызываем метод класса на NSString .

Теперь посмотрите на эту команду:

 [NSString stringWithFormat:@"%@%d", numberDisplay.text, val ]; 

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

Теперь, когда код в руках и настроенный интерфейс, пришло время соединить их с помощью Interface Builder. Перед тем, как сделать это, вам нужно создать свой проект, нажав кнопку « Построить и запустить в Xcode»; это гарантирует, что Interface Builder имеет все входы и выходы, доступные для него, так что вы можете соединить их с компонентами интерфейса.

Подключение интерфейса к коду

Интерфейсный Разработчик ищет элементы IBOutlet и IBAction класса представления Objective-C и предоставляет нам интерфейс для привязки к ним элементов управления. Чтобы связать кнопки, сначала выберите эту кнопку, затем перейдите на панель соединений окна инспектора (обозначена синим кружком со стрелкой).

Отсюда вы можете увидеть все события, связанные с кнопкой. Вы можете щелкнуть любой из кружков и перетащить его на элемент «Владелец файла» в окне содержимого. Для наших кнопок мы будем использовать событие «Touch Up Inside». Когда вы перетащите ваше событие на владельца файла , вы увидите всплывающее окно, в котором показаны все доступные методы IBAction . Просто выберите соответствующий: номер numberClicked на кнопку с plusClicked плюс plusClicked на знак плюс и так далее. Подключите все кнопки таким же образом.

Последний шаг — подключение переменной numberDisplay к элементу пользовательского интерфейса отображения чисел. Начните с перехода к окну содержимого и выберите владельца файла . Это должно показать что-то вроде рисунка ниже в окне инспектора.

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

На этом этапе вы можете сохранить интерфейс и закрыть Interface Builder. Затем попробуйте запустить приложение из среды разработки Xcode. Он должен работать более или менее так, как вы ожидаете, что калькулятор будет работать. Конечно, логика нашего приложения очень проста; Есть много способов улучшить поведение приложения.

Если калькулятор не работает, проблема, вероятно, связана с соединениями, которые вы определили между пользовательским интерфейсом (файл .xib) и файлом Objective-C. Следуйте инструкциям из предыдущей статьи, чтобы добавить точки останова к методам click в классе Objective-C и посмотреть, не вызваны ли методы. Если это не так, вернитесь к Интерфейсному Разработчику, чтобы убедиться, что вы связали правильные события с методами IBAction в классе Objective-C.

Куда пойти отсюда

Это только вершина айсберга, когда дело доходит до изучения Objective-C и разработки для устройств iOS. В этой статье мы узнали, как собрать проект, создать пользовательский интерфейс, подключить его к внутреннему классу Objective-C и заставить его что-то делать. Если приложение, которое вы имеете в виду, использует сеть, есть надежная библиотека HTTP, которую вы можете использовать. Если ваше идеальное приложение более графическое по своей природе, вас ждет удивительная библиотека графики и эффектов Quartz.

Не стесняйтесь использовать код в этой статье в качестве отправной точки. Если вы придумали что-то отличное, обязательно дайте мне знать, и я куплю это в App Store (при условии, что вы держите это относительно дешево!).