пятница, 25 января 2013 г.

Урок 5. Текстовое поле UITextField и протокол делегата UITextFieldDelegate

Всем привет!

Наступила новая неделя и мы продолжаем изучение iOS :)
В прошлом уроке мы узнали о том, как можно создавать интерфейс приложения "визуально", используя надписи, текстовые поля и т.д., а так же узнали, как мы можем задействовать элементы на экране в нашем коде и даже написали простенькое приложение на эту тему.

Сегодня мы более подробно познакомимся со свойствами UITextField и с понятием делегата.

Обработка событий в iOS

Давайте начнем с понятия делегата.
Представьте пример: пользователь открыл приложение, перед ним экран с несколькими элементами управления.
В зависимости от элемента управления, с ним можно выполнять те или иные действия - например, нажимать на текстовое поле и осуществлять ввод с экранной клавиатуры.
Или, если это прокручиваемая область, ее можно "прокручивать" пальцем в любых доступных направлениях. Или, если это "список" или "таблица", ее можно опять же прокручивать, "зачеркивать" элементы для их удаления и т.д.

Поскольку мы программисты, то вся забота по реакции на эти события лежит на нас.
На самом деле, часть заботы компания Apple взяла на себя - вся анимация при "скроллинге", вызов клавиатуры и отрисовка символов, которые вводит пользователь в текстовое поле - это и многое другое уже готово. Но, поскольку каждая программа уникальна, эппл не могла написать весь код за нас, поэтому обработку некоторых событий все-таки должны сделать мы.

Но как определить, что пользователь сделал что-то на экране? Возьмем наш конкретный случай - как определить, что пользователь начал вводить текст в текстовое поле (или закончил, нажав клавишу "return")?
Вот тут и появляется понятие делегата. Делегат - это объект, который будет "извещен" о том, что что-то произошло с конкретным элементом на экране.
В нашем случае, мы можем создать делегата, который будет оповещаться всякий раз, когда с текстовым полем произойдет то или иное событие - например, пользователь начнет набирать текст или закончит набор.
Сразу появляется несколько вопросов.
Во-первых, что значит "извещен"? Фактически, это означает, что наша программа сама вызовет специальный метод у объекта, который мы объявили делегатом. Чуть позже мы увидим, как это реализуется в коде.
Во-вторых, любой ли объект может быть делегатом? Нет, не любой. Поскольку программа вызывает специальные методы, она должна быть уверена, что у объекта они реализованы в коде (иначе программа сломается и упадет). Список методов, которые должны быть реализованы, чтобы объект мог называть себя делегатом и привязываться к объекту на экране (например, к тому же текстовому полю) называется протоколом.

Давайте еще раз, коротко.
Программист создает объект и реализует в коде все необходимые методы, указанные в протоколе. Потом привязывает (я позже объясню, как это делается) объект к текстовому полю. Потом запускает программу, нажимает на текстовое поле - текстовое поле обращается к своему делегату (которого, как мы помним, создал программист) и вызывает один из методов.

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

Отлично, все хорошо в теории.
А теперь давайте поучимся на практике.
Начнем с того, что нам нужен объект-делегат. В сложных программах для этого обычно создают отдельный класс, но поскольку мы только учимся - давайте сделаем делегатом наш ViewController. Как мы помним, нам надо сделать две вещи - сначала указать, что наш класс реализует протокол делегата текстового поля, а затем реализовать требуемые методы.

Протокол текстового поля называется UITextFieldDelegate.
Чтобы показать, что наш ViewController отвечает этому протоколу, зайдем в ViewController.h и в объявлении напишем

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITextFieldDelegate>
{
    IBOutlet UILabel *myText;
    IBOutlet UITextField *inputText;
}
@end

Отлично. Теперь надо реализовать все необходимые методы.
На самом деле, в протоколах методы бывают необходимые (required) и необязательные(optional), которые реализовывать не обязательно.
Конкретно в UITextFieldDelegate ВСЕ методы необязательные и можно вообще ничего не делать :)
Но мы реализуем один (пишем в ViewController.m)


-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
    myText.text = textField.text;
    [textField resignFirstResponder];
    return YES;
}


Этот метод вызывается, когда пользователь закончил редактирование и нажал на клавиатуре телефона кнопку return.
Здесь мы: 1) присваиваем надписи тот текст, который вел пользователь
2) убираем клавиатуру с экрана

Теперь остался последний момент - рассказать текстовому полю, что у него теперь есть делегат.
Для этого надо открыть наш ViewController_iPhone.xib, нажать правой кнопкой на текстовое поле и от кружочка в строке delegate провести линию на File owner:
Отлично!
Давайте теперь запустим.
Вот что получилось у меня:



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

1 комментарий: