|
Май
20
|
Одна из привлекательных особенностей интерфейса Cocoa Touch — упрощенная работа с анимацией. В этом уроке я покажу пару простых примеров создания анимации для iPhone. Наша анимация будет выполнять две задачи: перемещать объект на экране и менять его размеры в зависимости от точки касания его пользователем.
Тем, кому еще не приходилось заниматься программированием на iPhone, полезно будет ознакомится с азами [здесь]. В качестве примера приведу также урок из серии Stanford iPhone Development (в оригинале), где рассматривались основы анимации движения.
Ниже выложено короткое видео приложения, которое нам предстоит создать. Как уже упоминалось выше, с ним можно делать две вещи. Один щелчок будет перемещать внутреннее представление к точке касания. При двойном касании представление будет перемещаться с изменением размеров. Ориентируясь на точки касания, приложение создавать прямоугольник с фреймом для представления.
Что ж, приступаем… Первым делом нам нужен проект. Создав простое приложение Window-Based Application, добавим к нему представление. Для этого откройте в редакторе Interface Builder файл “MainWindow.xib“, дважды щелкнув по нему. В запущенном редакторе откроем окно библиотеки Library (командой Tools -> Library). Один из ее элементов — компонент View. Перетащите его в основное окно Window, ориентируясь на изображение ниже.

Теперь нужно сообщить основному представлению, что будут разрешен многокасательный метод работы. Это можно сделать в окне инспектора, вызываемом командой “Tools-> Attributes Inspector“. Убедитесь, что опция “Multiple Touch” в нижней части окна отмечена флажком.

Внутрь первого представления перетаскиваем второе — то самое, которое будет перемещаться и менять размер. Для второго представления нужно будет настроить ряд параметров: размер, цвет, исходное положение. Откорректировать размер и положение можно в окне инспектора размеров (Tools > Size Inspector). Я установил положение на 0, 0, размер — 30, 30. В окне инспектора атрибутов снимите флажок “User Interaction Enabled“.

Следующий шагом создадим пользовательский подкласс “UIView“, который будет включать весь код к этому уроку. Своему я присвоил имя “TouchView“.


В файл “TouchView.h” для малого внутреннего представления (перемещающегося и меняющего размер) добавьте переменную single instance. Присвоим ей метку “IBOutlet“, чтобы связать с представлением в редакторе IB. В итоге заголовочный файл будет выглядеть так:
1 2 3 4 5 6 7 | #import <UIKit/UIKit.h> @interface TouchView : UIView { IBOutlet UIView *strechView; } @end |
Чтобы связать в IB представление с пользовательским классом (custom class), укажем имя класса для представления. Для этого в редакторе IB выделим основное представление и откроем для него окно инспектора “Identity Inspector“. В поле “Class” в верхней части окна введите “TouchView“.
Вернемся в редактор и свяжем малое представление с переменной экземпляра. Для этого, удерживая нажатой клавишу <Control>, щелкните на основном представлении и перетащите его на малое. В открывшемся окне появятся варианты опций для связи. Нам необходим метод “strechView“.

Остальная часть кода относится к “TouchView.m“. Для начала удалите все текущий код, поскольку нам не понадобится ни один из внедренных в нем методов. Впрочем, можно добавить приведенный ниже фрагмент, обрабатывающий момент касания экрана.
1 2 3 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { } |
Первым делом нужно запустить анимацию. За это будет отвечать метод “beginAnimations:context:” класса “UIView“. Мы передаем ему имя анимации и “nil” в качестве контекста. В моем случае именем будет @”MoveAndStrech”. Для запуска и прекращения анимации обратимся к методу класса “commitAnimations“. События между двумя запросами и представляют собой собственно анимацию. Быстро настроить поведение анимации помогут два метода: “setAnimationDuration:” и “setAnimationBeginsFromCurrentState“. Функция первого, в принципе, ясна из названия, а второй сообщает анимации о том, что начинаться она будет с текущего состояния представления. Вот как будет выглядеть обновленный метод “touchesBegan“:
1 2 3 4 5 6 7 8 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [UIView beginAnimations:@"MoveAndStrech" context:nil]; [UIView setAnimationDuration:1]; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView commitAnimations]; } |
Оставшаяся часть кода отвечает за обновление представления. Сначала рассмотрим ситуацию с одним касанием. В этом случае мы получаем объект “UITouch” из множества “touches“. Затем устанавливаем центр “strechVie” на точку касания относительно основного представления (self). В итоге в двух простых строках имеем перемещающееся представление, следующее за касанием.
1 2 3 4 5 6 7 8 9 10 11 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [UIView beginAnimations:@"MoveAndStrech" context:nil]; [UIView setAnimationDuration:1]; [UIView setAnimationBeginsFromCurrentState:YES]; if([touches count] == 1) { UITouch *touch = [touches anyObject]; strechView.center = [touch locationInView:self]; } [UIView commitAnimations]; } |
Осталось лишь реализовать изменение размеров представления. Ниже мы подробно рассмотрим следующий фрагмент:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [UIView beginAnimations:@"MoveAndStrech" context:nil]; [UIView setAnimationDuration:1]; [UIView setAnimationBeginsFromCurrentState:YES]; if([touches count] == 1) { UITouch *touch = [touches anyObject]; strechView.center = [touch locationInView:self]; } else if([touches count] == 2) { NSArray *touchArray = [touches allObjects]; UITouch *touchOne = [touchArray objectAtIndex:0]; UITouch *touchTwo = [touchArray objectAtIndex:1]; CGPoint pt1 = [touchOne locationInView:self]; CGPoint pt2 = [touchTwo locationInView:self]; CGFloat x, y, width, height; if(pt1.x < pt2.x) { x = pt1.x; width = pt2.x - pt1.x; } else { x = pt2.x; width = pt1.x - pt2.x; } if(pt1.y < pt2.y) { y = pt1.y; height = pt2.y - pt1.y; } else { y = pt2.y; height = pt1.y - pt2.y; } strechView.frame = CGRectMake(x, y, width, height); } [UIView commitAnimations]; } |
Для перемещения представления с изменением размеров необходимо зафиксировать два касания. Это легко выполнит метод экземпляра класса “allObjects” на множестве “touches“. Получаем оба адреса и определяем верхние координаты x и y. Ширина и высота рассчитываются из разницы координат. Последним шагом задаем “frame” для представления с помощью “CGRectMake“. Итоговый файл “TouchView.m” приведен ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #import "TouchView.h" @implementation TouchView - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [UIView beginAnimations:@"MoveAndStrech" context:nil]; [UIView setAnimationDuration:1]; [UIView setAnimationBeginsFromCurrentState:YES]; if([touches count] == 1) { UITouch *touch = [touches anyObject]; strechView.center = [touch locationInView:self]; } else if([touches count] == 2) { NSArray *touchArray = [touches allObjects]; UITouch *touchOne = [touchArray objectAtIndex:0]; UITouch *touchTwo = [touchArray objectAtIndex:1]; CGPoint pt1 = [touchOne locationInView:self]; CGPoint pt2 = [touchTwo locationInView:self]; CGFloat x, y, width, height; if(pt1.x < pt2.x) { x = pt1.x; width = pt2.x - pt1.x; } else { x = pt2.x; width = pt1.x - pt2.x; } if(pt1.y < pt2.y) { y = pt1.y; height = pt2.y - pt1.y; } else { y = pt2.y; height = pt1.y - pt2.y; } strechView.frame = CGRectMake(x, y, width, height); } [UIView commitAnimations]; } @end |
Вот, собственно, и все. Обсуждаем, учимся

(7 голосов, средний: 4.86 из 5)
Сентябрь 23rd, 2011 at 09:25
В 4-м xCode главное представление не присоединяется к малому перетягиванием. Как это сделать по другому?