Действие — это сообщение, посылаемое экземпляром подкласса, производного от класса UlControl.

Оно уведомляет о важном событии, происходящем в элементе управления пользовательского интерфейса (см. главу 7). Все подклассы, производные от класса UlControl, представляют простые интерфейсные объекты, с которыми может непосредственно взаимодействовать пользователь. К их числу относится кнопка (UIButton), переключатель (UlSwitch), сегментированный элемент управления (UlSegmentedControl), ползунок (UlSlider) или текстовое поле (UITextField).

Самые важные пользовательские (или управляющие) события перечислены в разделе, посвященном событиям и константам документации на класс UlControl. В разных элементах управления реализуются разные управляющие события. Например, событие Value Changed сегментированного элемента управления обозначает, что пользователь выбрал другой сегмент, тогда как событие Touch Up Inside пользователь выбрал нажатием кнопки. Само управляющее событие не имеет никакого действия. Элемент управления реагирует на него визуально (например, нажатая кнопка выглядит нажатой), но ни с кем не обменивается информацией о наступившем событии. Если требуется выяснить, когда наступает управляющее событие, чтобы вовремя отреагировать на него в прикладном коде, необходимо сделать так, чтобы это управляющее событие инициировало сообщение о действии.

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

быть любое количество пар “цель-действие”, где действие — это селектор сообщений (имя метода), а цель — объект, которому посылается сообщение. Когда наступает управляющее событие, элемент управления обращается к таблице диспетчеризации, находит в ней пару “цель-действие”, связанную с данным управляющим событием, а затем посылает каждое сообщение о действии соответствующей цели (рис. 11.1).

 

 Архитектура

Рис. 11.1. Архитектура "цель-действие"

 

Манипулировать действием таблицы диспетчеризации действий в элементе управления можно двумя способами: установить связь с действием в nib-файле, как пояснялось в главе 7, или сделать это программно в прикладном коде. В последнем случае элементу управления посылается сообщение addTarget: action: forControlEvents:, где параметр target: обозначает объект, параметр action: — селектор, а параметр ControlEvents: — битовую маску (о том, как составляется битовая маска, см. в главе 1). В отличие от центра уведомлений, у элемента управления имеются также методы для интроспекции таблицы диспетчеризации.

Вернемся к примеру из главы 7. Напомним, что в этом примере имеется метод buttonPressed:, который должен вызываться, когда пользователь нажимает определенную кнопку в интерфейсе. Исходный код этого метода приведен ниже.

- (void) buttonPressed: (id) sender (

UIAlertView* av = [[UIAlertView alloc] initWithTitle:@"Howdy!"

message:®"You tapped me." delegate:nil

cancelButtonTitle:@"Cool" otherButtonTitles:nil];

[av show];

}

 

Для того чтобы это произошло, в главе 7 была установлена связь с действием в nib-файле, а именно: событие касания кнопки Touch Up Inside было связано с методом buttonPressed: из класса ViewController. В действительности это означало формирование пары “цель-действие”, где целью был экземпляр класса ViewController, владевший nib-файлом после его загрузки, тогда как действием — селектор buttonPressed:, а также ввод этой пары в таблицу диспетчеризации для управляющего события Touch Up Inside.

Вместо установления подобной связи в nib-файле то же самое можно было бы сделать непосредственно в прикладном коде. Допустим, что данная связь с действием не установлена и что вместо нее имеется связь с выходом, которая установлена от контроллера представления к кнопке и называется button. (На самом деле такая связь была установлена в главе 7.) В таком случае после загрузки nib-файла в контроллере представления можно настроить таблицу диспетчеризации кнопки следующим образом:

[self.button addTarget:self action:^selector(buttonPressed:)

forControlEvents :UIControlEventTouchUpInside] ;

 

Управляющее событие может иметь несколько пар “цель-действие”. Такую конфигурацию данного события можно сделать как намеренно, так и случайно. Снабдив управляющее событие парой “цель-действие” ненамеренно, но не удалив существующую пару “цель-действие”, можно очень легко совершить ошибку и тем самым вызвать совершенно загадочное поведение. Так, если установить в nib-файле связь с действием и настроить таблицу диспетчеризации в прикладном коде, то нажатие кнопки приведет к тому, что метод buttonPressed: будет вызван дважды.

 

Сигнатура селектора действия может быть представлена в трех формах.

• Простейшая форма принимает два параметра:

• Элемент управления, обычно обозначаемый как id.

• Объект класса UIEvent, инициировавший управляющее событие.

• Более короткая и чаще всего применяемая форма без второго параметра. Ее примером служит метод buttonPressed:, принимающий единственный параметр sender. Когда метод buttonPressed: вызывается по сообщению о действии, исходящему от кнопки, параметр sender будет служить ссылкой на кнопку.

• Имеется и еще более короткая форма, в которой опущены оба параметра.

Что же собой представляет класс UIEvent и для чего он предназначен? Событие касания инициируется всякий раз, когда пользователь совершает какое-нибудь движение пальцем (опускает его на экран, перемещает по нему, поднимает от экрана). Объекты класса UIEvent относятся к числу низкоуровневых объектов, отвечающих за передачу событий касания приложению. По существу, объект типа UIEvent представляет собой временную метку (двойную) наряду с коллекцией (типа NSSet) событий касания (типа UITouch). Механизм действий намеренно скрывает все сложные детали формирования событий касания, но если выбрать получение объекта типа UIEvent, то при желании можно добраться до этих сложных деталей.

Любопытно, что ни один из параметров селектора действия не позволяет выяснить, какое именно управляющее событие привело к вызову текущего селектора действия! Например,

для того чтобы отличить управляющее событие Touch Up Inside от управляющего события Touch Up Outside, в соответствующих им парах “цель-действие” необходимо указать два разных обработчика действий. Если же передать эти события одному и тому же обработчику действий, то он не сумеет распознать, какое именно управляющее событие произошло.

 

Предупреждение для программистов в системе OS X

Если у вас имеется опыт разработки приложений в среде Cocoa под OS X, вы, вероятно, обратите внимание на некоторые основные отличия в реализации действий в системах OS X и iOS. В частности, у элемента управления в OS X имеется лишь одно действие, тогда как в iOS единственное событие может инициировать передачу многих сообщений о действиях нескольким целям. Кроме того, в системе OS X селектор сообщений о действиях принимает единственную форму, тогда как в системе iOS возможны три его формы.


 

 

 

Добавить комментарий