- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания iOS. Приемы программирования - Вандад Нахавандипур
Шрифт:
Интервал:
Закладка:
/* Берем предыдущее значение вращения и суммируем его с актуальным
значением вращения. */
self.helloWorldLabel.transform =
CGAffineTransformMakeRotation(self.rotationAngleInRadians +
paramSender.rotation);
/* Когда значение завершится, сохраняем полученный угол для
дальнейшего использования. */
if (paramSender.state == UIGestureRecognizerStateEnded){
self.rotationAngleInRadians += paramSender.rotation;
}
}
Распознаватель жестов вращения посылает нам информацию об углах вращения очень интересным способом. Этот распознаватель является непрерывным. Это означает, что распознаватель приступает к вычислению углов, как только пользователь начинает жест вращения, и отправляет обновления методу-обработчику с краткими интервалами до тех пор, пока пользователь не закончит жест. В каждом сообщении начальный угол воспринимается как нулевой, и это сообщение содержит информацию о начальной точке вращения (достигнутой после окончания предыдущего акта вращения) и конечной точке. Таким образом, полный эффект от данного жеста можно узнать, только суммировав значения углов, полученные в результате различных событий. Движение по часовой стрелке дает положительное угловое значение, а против часовой стрелки — отрицательное.
Если вы работаете с симулятором iPhone, а не с реальным устройством, то можете имитировать и вращательное движение. Для этого нужно просто удерживать клавишу Option. В симуляторе вы увидите два кружка, которые появятся на одинаковом расстоянии от центра экрана. Они будут соответствовать подушечкам двух пальцев. Если вы захотите переместить «пальцы» из центра в другую точку экрана, то нужно нажать клавишу Shift, удерживая Alt, и перейти в желаемую точку. Когда вы отпустите указатель, новая точка станет центром для двух подушечек пальцев.
Теперь мы просто присвоим этот угол углу вращения метки. Но вы можете представить, что произойдет, когда одно вращение закончится, а другое начнется? Угол второго вращательного жеста заменит первое вращение в значении rotation и будет сообщен обработчику. Поэтому, как только вращательный жест завершится, необходимо сохранить текущее вращательное значение метки. Угловое значение, получаемое в результате каждого вращательного движения, должно суммироваться с предыдущими по очереди. Ранее было показано, как этот результат присваивается общему вращательному преобразованию метки.
Кроме того, прежде мы говорили о применении функции CGAffineTransformMakeRotation для создания аффинного преобразования. Функции iOS SDK, названия которых начинаются на CG, относятся к фреймворку Core Graphics. Чтобы в программах, использующих Core Graphics, успешно протекали процессы компиляции и связывания, необходимо убедиться, что Core Graphics добавлен в список фреймворков. В новых версиях Xcode стандартный проект автоматически связывается с фреймворком Core Graphics, так что об этом можно не беспокоиться.
Теперь, когда вы уверены, что фреймворк Core Graphics добавлен к целевой сборке, можно скомпилировать и запустить приложение.
См. также
Раздел 10.6.
10.3. Обнаружение жестов панорамирования и перетаскивания
Постановка задачи
Требуется предоставить пользователю возможность перемещать элементы в пользовательском интерфейсе, касаясь сенсорного экрана пальцами.
Жесты панорамирования — это непрерывные движения пальцев по экрану. Напоминаю, что жесты смахивания являются дискретными. Это означает, что метод, задаваемый для распознавателя жестов панорамирования в качестве целевого, вызывается многократно от начала и до конца процесса распознавания.
Решение
Воспользуйтесь классом UIPanGestureRecognizer:
— (void)viewDidLoad {
[super viewDidLoad];
/* Сначала создаем метку. */
CGRect labelFrame = CGRectMake(0.0f, /* X */
0.0f, /* Y */
150.0f, /* Ширина */
100.0f); /* Высота */
self.helloWorldLabel = [[UILabel alloc] initWithFrame: labelFrame];
self.helloWorldLabel.text = @"Hello World";
self.helloWorldLabel.backgroundColor = [UIColor blackColor];
self.helloWorldLabel.textColor = [UIColor whiteColor];
self.helloWorldLabel.textAlignment = UITextAlignmentCenter;
/* Убеждаемся, что мы активизировали пользовательские взаимодействия;
в противном случае эта метка не будет фиксировать события нажатия. */
self.helloWorldLabel.userInteractionEnabled = YES;
/* А теперь убеждаемся, что метка отображается в виде. */
[self.view addSubview: self.helloWorldLabel];
/* Создаем распознаватель жестов панорамирования. */
self.panGestureRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget: self
action:@selector(handlePanGestures:)];
/* Для активизации распознавателя жестов панорамирования требуется
один палец. */
self.panGestureRecognizer.minimumNumberOfTouches = 1;
self.panGestureRecognizer.maximumNumberOfTouches = 1;
/* Добавляем распознаватель к виду. */
[self.helloWorldLabel addGestureRecognizer: self.panGestureRecognizer];
}
Распознаватель жестов панорамирования будет вызывать метод handlePanGestures: в качестве целевого. Этот метод описан в подразделе «Решение» данного раздела.
Обсуждение
Распознаватель UIPanGestureRecognizer, как понятно из его названия[9], способен обнаруживать жесты панорамирования. В ходе работы этот распознаватель проходит через следующие состояния:
• UIGestureRecognizerStateBegan;
• UIGestureRecognizerStateChanged;
• UIGestureRecognizerStateEnded.
Целевой метод этого распознавателя жестов можно реализовать следующим образом. Приведенный код будет непрерывно перемещать центр метки вслед за пальцем пользователя, и на протяжении этого процесса будет сообщаться о событиях GestureRecognizerStateChanged:
— (void) handlePanGestures:(UIPanGestureRecognizer*)paramSender{
if (paramSender.state!= UIGestureRecognizerStateEnded &&
paramSender.state!= UIGestureRecognizerStateFailed){
CGPoint location = [paramSender
locationInView: paramSender.view.superview];
paramSender.view.center = location;
}
}
Чтобы можно было перемещать метку вида, относящегося к контроллеру вида, нам нужно знать не положение метки, а положение пальца на виде. Поэтому мы вызываем метод locationInView: распознавателя жестов панорамирования и передаем родительский вид метки в качестве целевого.
Воспользуйтесь методом locationInView: распознавателя жестов панорамирования, чтобы найти позиции пальцев (или пальца), которые в настоящее время совершают этот жест. Чтобы найти положение нескольких пальцев, пользуйтесь методом locationOfTouch: inView:. С помощью свойств minimumNumberOfTouches и maximumNumberOfTouches класса UIPanGestureRecognizer можно одновременно регистрировать более одного панорамирующего касания. Но в примере ради простоты мы пытаемся найти положение всего одного пальца.
В состоянии UIGestureRecognizerStateEnded сообщаемые значения x и y могут быть и нечисловыми — они могут равняться NAN. Вот почему необходимо избегать использования значений, сообщаемых именно в этом конкретном состоянии.
10.4. Обнаружение жестов долгого нажатия
Постановка задачи
Необходимо обнаруживать ситуации, в которых пользователь нажимает определенный экранный элемент и удерживает палец на экране в течение некоторого периода времени.
Решение
Создайте экземпляр класса UILongPressGestureRecognizer и добавьте его к виду, в котором требуется распознавать жесты долгого нажатия. h-файл контроллера вида будет определяться следующим образом:
#import «ViewController.h»
@interface ViewController ()
@property (nonatomic, strong)
UILongPressGestureRecognizer *longPressGestureRecognizer;
@property (nonatomic, strong) UIButton *dummyButton;
@end
@implementation ViewController
Далее приведен метод экземпляра viewDidLoad, относящийся к контроллеру вида, где используется распознаватель долгих нажатий. Этот распознаватель реализован в следующем. m-файле:
— (void)viewDidLoad {
[super viewDidLoad];
self.dummyButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
self.dummyButton.frame = CGRectMake(0.0f,
0.0f,
72.0f,
37.0f);
self.dummyButton.center = self.view.center;
[self.view addSubview: self.dummyButton];
/* Сначала создаем распознаватель жестов. */
self.longPressGestureRecognizer =
[[UILongPressGestureRecognizer alloc]
initWithTarget: self
action:@selector(handleLongPressGestures:)];
/* Количество пальцев, которые должны находиться на экране. */