Текст книги "iOS. Приемы программирования"
Автор книги: Вандад Нахавандипур
Жанр: Зарубежная компьютерная литература, Зарубежная литература
сообщить о неприемлемом содержимом
Текущая страница: 55 (всего у книги 59 страниц)
Раздел 17.3.
17.11. Перемещение фигур, нарисованных в графических контекстах
Постановка задачиТребуется переместить все, что изображено в графическом контексте, на новое место, не изменяя при этом кода отрисовки, либо просто без труда сместить содержимое графического контекста.
РешениеВоспользуйтесь функцией CGAffineTransformMakeTranslation для создания аффинного преобразования сдвига.
ОбсуждениеВ разделе 17.8 было упомянуто о преобразованиях. Преобразование – это, в сущности, просто изменение способа отображения рисунка. Преобразования в Core Graphics – это объекты, применяемые к фигурам перед отрисовкой последних. Например, можно создать преобразование сдвига (Translation Transformation). «Сдвига чего?» – могли бы спросить вы. Дело в том, что преобразование сдвига – это механизм, позволяющий сместить фигуру или графический контекст.
Среди других типов преобразований следует также назвать вращение (см. раздел 17.13) и масштабирование (см. раздел 17.12). Все это примеры аффинных преобразований, то есть при таком преобразовании каждая точка оригинала сопоставляется с другой точкой в окончательной версии. Все преобразования, о которых мы будем говорить в этой книге, являются аффинными.
В ходе преобразования сдвига актуальное положение фигуры на пути или в графическом контексте сдвигается на другую относительную позицию. Например, если вы поставите точку с координатами (10; 20), примените к ней преобразование сдвига (30; 40) и снова ее поставите, точка окажется расположенной в координатах (40; 60), поскольку 40 = 10 + 30, а 60 = 20 + 40.
Чтобы создать новое преобразование сдвига, используется функция CGAffineTransformMakeTranslation, которая возвращает аффинное преобразование типа CGAffineTransform. Два параметра этой функции указывают сдвиг по осям X и Y в точках.
В разделе 17.8 мы изучили, что процедура CGPathAddRect принимает в качестве второго параметра объект преобразования типа CGAffineTransform. Чтобы сместить прямоугольник с его исходной позиции на другую, можно просто создать аффинное преобразование, указывающее изменения, которые вы хотели бы применить к координатам x и y, и передать преобразование второму параметру процедуры CGPathAddRect, как показано далее:
– (void)drawRect:(CGRect)rect{
/* Сначала создаем путь. Просто описатель пути. */
CGMutablePathRef path = CGPathCreateMutable();
/* Это границы прямоугольника. */
CGRect rectangle = CGRectMake(10.0f,
10.0f,
200.0f,
300.0f);
/* Мы хотим сместить прямоугольник на 100 точек вправо,
не изменив при этом его положения по оси Y. */
CGAffineTransform transform = CGAffineTransformMakeTranslation(100.0f,
0.0f);
/* Добавляем прямоугольник к пути. */
CGPathAddRect(path,
&transform,
rectangle);
/* Получаем описатель текущего контекста. */
CGContextRef currentContext =
UIGraphicsGetCurrentContext();
/* Добавляем путь к контексту. */
CGContextAddPath(currentContext,
path);
/* Задаем голубой в качестве цвета заливки. */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Задаем для обводки коричневый цвет. */
[[UIColor brownColor] setStroke];
/* Задаем для ширины (обводки) значение 5. */
CGContextSetLineWidth(currentContext,
5.0f);
/* Проводим путь в контексте и применяем к нему заливку. */
CGContextDrawPath(currentContext,
kCGPathFillStroke);
/* Избавляемся от пути. */
CGPathRelease(path);
}
На рис. 17.30 показан результат выполнения этого блока кода внутри объекта-вида.
Сравните рис. 17.30 и 17.22. Видите разницу? Еще раз просмотрите исходный код для обеих фигур и убедитесь в том, что положения по осям X и Y, указанные для обоих прямоугольников, в обоих блоках кода идентичны. Различие заключается только в том, что на рис. 17.30 мы видим результат применения к прямоугольнику аффинного преобразования, когда прямоугольник добавляется к пути.
Кроме применения преобразований к фигурам, отрисовываемым относительно путей, мы можем применять преобразования и к графическому контексту с помощью процедуры CGContextTranslateCTM. Она применяет преобразование к текущей матрице преобразований (Current Transformation Matrix, CTM). Хотя это название и может показаться сложным, понять его смысл не составляет труда. Считайте CTM правилами, определяющими расположение центра вашего графического контекста, а также правилами проецирования каждой отрисовываемой точки на экране. Например, если вы приказываете Core Graphics поставить точку с координатами (0; 0), Core Graphics найдет центр экрана, получив эту информацию из текущей матрицы преобразований. Затем CTM выполнит определенные вычисления и сообщит Core Graphics, что искомая точка расположена в верхнем левом углу экрана. С помощью таких процедур, как CGContextTranslateCTM, можно изменить конфигурацию этой матрицы, после чего заставить все фигуры, отрисованные в графическом контексте, занять на холсте другие позиции. Вот пример, в котором мы достигаем точно такого же эффекта, как и на рис. 17.30, но применяем преобразование сдвига не к самому прямоугольнику, а к текущей матрице преобразований:
Рис. 17.30. Прямоугольник с аффинным преобразованием сдвига
– (void)drawRect:(CGRect)rect{
/* Сначала создаем путь. Просто описатель пути. */
CGMutablePathRef path = CGPathCreateMutable();
/* Это границы прямоугольника. */
CGRect rectangle = CGRectMake(10.0f,
10.0f,
200.0f,
300.0f);
/* Добавляем прямоугольник к пути. */
CGPathAddRect(path,
NULL,
rectangle);
/* Получаем описатель текущего контекста. */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Сохраняем состояние контекста, чтобы позже
можно было восстановить это состояние. */
CGContextSaveGState(currentContext);
/* Сдвигаем текущую матрицу преобразований
на 100 точек вправо. */
CGContextTranslateCTM(currentContext,
100.0f,
0.0f);
/* Добавляем путь к контексту. */
CGContextAddPath(currentContext,
path);
/* Задаем голубой в качестве цвета заливки. */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Задаем для обводки коричневый цвет. */
[[UIColor brownColor] setStroke];
/* Задаем для ширины (обводки) значение 5. */
CGContextSetLineWidth(currentContext,
5.0f);
/* Проводим путь в контексте и применяем к нему заливку. */
CGContextDrawPath(currentContext,
kCGPathFillStroke);
/* Избавляемся от пути. */
CGPathRelease(path);
/* Восстанавливаем состояние контекста. */
CGContextRestoreGState(currentContext);
}
Запустив эту программу, вы получите точно такие же результаты, как и на рис. 17.30.
См. такжеРазделы 17.8, 17.12 и 17.13.
17.12. Масштабирование фигур, нарисованных в графических контекстах
Постановка задачиТребуется динамически масштабировать фигуры, отрисованные в графическом контексте, в сторону уменьшения или увеличения.
РешениеСоздайте аффинное преобразование масштаба, воспользовавшись функцией CGAffineTransformMakeScale.
ОбсуждениеВ разделе 17.11 было объяснено, что такое преобразование и как применять его к фигурам и графическим контекстам. Один из вариантов преобразования, которым вы можете воспользоваться, – это масштабирование. Core Graphics позволяет без проблем масштабировать фигуру, например круг, на 100 % относительно ее исходного размера.
Чтобы создать аффинное преобразование масштаба, пользуйтесь функцией CGAffineTransformMakeScale, которая возвращает объект преобразования типа CGAffineTransform. Если вы хотите применить преобразование масштаба непосредственно к графическому контексту, примените процедуру CGContextScaleCTM, которая масштабирует CTM. Подробнее о CTM (текущей матрице преобразований) рассказано в разделе 17.11.
Функции преобразования масштаба принимают два параметра: масштабирование по оси X и масштабирование по оси Y. Еще раз обратимся к прямоугольнику с рис. 17.22. Если мы хотим масштабировать этот прямоугольник, чтобы его исходные длина и ширина уменьшились вполовину, то можно просто масштабировать по оси X и Y на 0,5 (вполовину от исходного значения), как показано здесь:
/* Масштабируем прямоугольник, уменьшая его на половину. */
CGAffineTransform transform =
CGAffineTransformMakeScale(0.5f, 0.5f);
/* Добавляем прямоугольник к пути. */
CGPathAddRect(path,
&transform,
rectangle);
На рис. 17.31 показано, что получится, когда мы применим преобразование масштаба к коду, написанному в разделе 17.8.
Рис. 17.31. Масштабирование прямоугольника
Дополнительно к функции CGAffineTransformMakeScale можно использовать процедуру CGContextScaleCTM, помогающую применить преобразование масштаба к графическому контексту. Следующий код даст тот же эффект, что и в предыдущем примере (вновь обратите внимание на рис. 17.31):
– (void)drawRect:(CGRect)rect{
/* Сначала создаем путь. Просто описатель пути. */
CGMutablePathRef path = CGPathCreateMutable();
/* Это границы прямоугольника. */
CGRect rectangle = CGRectMake(10.0f,
10.0f,
200.0f,
300.0f);
/* Добавляем прямоугольник к пути. */
CGPathAddRect(path,
NULL,
rectangle);
/* Получаем описатель текущего контекста. */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Масштабируем все фигуры, отрисованные в графическом контексте,
уменьшая их на половину. */
CGContextScaleCTM(currentContext,
0.5f,
0.5f);
/* Добавляем путь к контексту. */
CGContextAddPath(currentContext,
path);
/* Задаем голубой в качестве цвета заливки. */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Задаем для обводки коричневый цвет. */
[[UIColor brownColor] setStroke];
/* Задаем для ширины (обводки) значение 5. */
CGContextSetLineWidth(currentContext,
5.0f);
/* Проводим путь в контексте и применяем к нему заливку. */
CGContextDrawPath(currentContext,
kCGPathFillStroke);
/* Избавляемся от пути. */
CGPathRelease(path);
}
Раздел 17.11.
17.13. Вращение фигур, нарисованных в графических контекстах
Постановка задачиТребуется иметь возможность вращать содержимое, отрисованное в графическом контексте, не изменяя при этом код отрисовки.
РешениеВоспользуйтесь функцией CGAffineTransformMakeRotation для создания аффинного преобразования вращения.
ОбсуждениеПеред тем как приступать к работе с этим разделом, настоятельно рекомендую вам перечитать материал из разделов 17.11 и 17.12. Чтобы сократить текст, я старался не дублировать в последующих разделах материал, уже изложенный в предыдущих.
Точно так же, как при масштабировании и сдвиге, мы можем применять преобразование вращения к фигурам, отрисованным на путях и прямо в графическом контексте. Можно использовать функцию CGAffineTransformMakeRotation и сообщать значение вращения в радианах, а в качестве возвращаемого значения получать преобразование вращения типа CGAffineTransform. Затем это преобразование можно применять к путям и фигурам. Если вы хотите повернуть весь контекст на определенный угол, используйте процедуру CGContextRotateCTM.
Повернем прямоугольник, изображенный на рис. 17.22, на 45° по часовой стрелке (рис. 17.32). Значение, полученное в результате вращения, должно быть выражено в радианах. Положительные значения дают вращение по часовой стрелке, а отрицательные – против часовой:
/* Вращаем прямоугольник на 45° по часовой стрелке. */
CGAffineTransform transform =
CGAffineTransformMakeRotation((45.0f * M_PI) / 180.0f);
/* Добавляем прямоугольник к пути. */
CGPathAddRect(path,
&transform,
rectangle);
Рис. 17.32. Вращение прямоугольника
Как было показано в разделе 17.12, мы можем применить преобразование и непосредственно к графическому контексту – с помощью процедуры CGContextRotateCTM.
См. такжеРазделы 17.11 и 17.12.
17.14. Анимирование и перемещение видов
Постановка задачиТребуется анимировать смещение видов.
РешениеПри смещении видов используйте анимационные методы класса UIView.
ОбсуждениеВ операционной системе iOS предоставляются различные способы выполнения анимации, среди этих возможностей есть как низкоуровневые, так и сравнительно высокоуровневые. Самый высокий уровень работы в данном случае обеспечивается во фреймворке UIKit, о котором мы также поговорим в этом разделе. В UIKit содержится некоторая низкоуровневая функциональность Core Animation, предоставляемая нам в форме довольно аккуратного API, с которым очень удобно работать.
Работа с анимацией в UIKit начинается с вызова метода класса beginAnimations: context:, относящегося к классу UIView. Первый параметр – это опциональное имя, которое вы можете выбрать для вашей анимации, а второй – опциональный контекст, который можно получить позже для передачи анимационным методам делегатов. Вскоре мы поговорим о них обоих.
После того как вы запустите анимацию с помощью метода beginAnimations: context:, она не начнет происходить, так как для этого потребуется еще вызвать метод класса commitAnimations, относящийся к классу UIView. Вычисления, которые вы производите над объектом-видом между вызовом beginAnimations: context: и commitAnimations (в результате которых этот вид, к примеру, перемещается), будут сопровождаться анимацией только после вызова commitAnimations. Рассмотрим пример.
Как упоминалось в разделе 17.4, я включил в пакет моего приложения рисунок Xcode.png. Это ярлык Xcode, который я нашел в картинках Google (см. рис. 17.9). Теперь в моем контроллере вида (см. введение к этой главе) я хочу поместить этот рисунок в виде с изображением типа UIImageView, а потом переместить этот вид с изображением из верхнего левого угла экрана в нижний правый угол.
Вот как мы решим эту задачу.
1. Откройте. h-файл вашего контроллера вида.
2. Определите экземпляр UIImageView как свойство контроллера вида и назовите его xcodeImageView:
#import «ViewController.h»
@interface ViewController ()
@property (nonatomic, strong) UIImageView *xcodeImageView;
@end
3. Когда вид загрузится, поместите изображение Xcode.png в экземпляр UIImage:
– (void) viewDidLoad{
[super viewDidLoad];
UIImage *xcodeImage = [UIImage imageNamed:@"Xcode.png"];
self.xcodeImageView = [[UIImageView alloc]
initWithImage: xcodeImage];
/* Просто задаем размеры, чтобы изображение уменьшилось. */
[self.xcodeImageView setFrame: CGRectMake(0.0f,
0.0f,
100.0f,
100.0f)];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview: self.xcodeImageView];
}
4. На рис. 17.33 показано, как будет выглядеть вид, когда программа запускается в симуляторе iOS.
Рис. 17.33. Добавление вида с изображением в объект-вид
5. Теперь, когда вид появится на экране в методе экземпляра viewDidAppear: контроллера вида, приступим к исполнению анимационного блока, относящегося к виду с изображением. Эта анимация переместит изображение из исходной точки (в левом верхнем углу) в нижний правый угол. Кроме того, мы убедимся, что анимация произойдет за пятисекундный период:
– (void) viewDidAppear:(BOOL)paramAnimated{
[super viewDidAppear: paramAnimated];
/* Начинаем с верхнего левого угла. */
[self.xcodeImageView setFrame: CGRectMake(0.0f,
0.0f,
100.0f,
100.0f)];
[UIView beginAnimations:@"xcodeImageViewAnimation"
context:(__bridge void *)self.xcodeImageView];
/* Пятисекундная анимация. */
[UIView setAnimationDuration:5.0f];
/* Получаем делегаты анимации. */
[UIView setAnimationDelegate: self];
[UIView setAnimationDidStopSelector:
@selector(imageViewDidStop: finished: context:)];
/* Анимация заканчивается в нижнем правом углу. */
[self.xcodeImageView setFrame: CGRectMake(200.0f,
350.0f,
100.0f,
100.0f)];
[UIView commitAnimations];
}
6. Далее выполните реализацию метода делегата imageViewDidStop: finished: context: для контроллера вида, чтобы он вызывался UIKit по завершении анимации. Это не обязательно, так что для примера я просто зарегистрирую несколько сообщений, демонстрирующих, что метод действительно был вызван. В следующих примерах будет показано, как можно использовать метод для запуска какой-то иной активности в момент окончания анимации:
– (void)imageViewDidStop:(NSString *)paramAnimationID
finished:(NSNumber *)paramFinished
context:(void *)paramContext{
NSLog(@"Animation finished.");
NSLog(@"Animation ID = %@", paramAnimationID);
UIImageView *contextImageView = (__bridge UIImageView *)paramContext;
NSLog(@"Image View = %@", contextImageView);
}
Теперь, запустив приложение, вы заметите, что, как только отобразится вид, изображение, показанное на рис. 17.33, начнет перемещаться в нижний правый угол (рис. 17.34). На это уйдет 5 секунд.
Рис. 17.34. Анимируемое изображение переходит в правый нижний угол экрана
Кроме того, обратив внимание на консоль и дождавшись окончания анимации, вы увидите примерно следующий текст:
Animation finished.
Animation ID = xcodeImageViewAnimation
Image View = <UIImageView: 0x8eaee20;
frame = (220 468; 100 100); opaque = NO;
userInteractionEnabled = NO;
layer = <CALayer: 0x8eaef10>>
А теперь рассмотрим конкретные концепции и разберемся, как именно мы анимировали этот вид с изображением. Далее перечислены важные методы класса, относящиеся к UIView, о которых нужно знать, занимаясь анимацией с UIKit.
• beginAnimations: context: – запускает анимационный блок. Любое анимируемое изменение свойств, которое вы применяете к видам после вызова этого метода класса, будет вступать в силу после выполнения анимации.
• setAnimationDuration: – этот метод задает длительность анимации в секундах.
• setAnimationDelegate: – задает объект, который будет получать сообщения делегатов, касающиеся различных событий, которые могли произойти до, во время или после анимации. Если мы задаем объект делегата, это не означает, что анимационные делегаты немедленно запускаются. Кроме того, вы должны использовать различные методы-установщики, относящиеся к классу, применяя их к объекту вида. Так вы сообщаете UIKit, какие селекторы в вашем объекте-делегате какие делегатные сообщения должны получать.
• setAnimationDidStopSelector: – задает в объекте-делегате метод, который должен быть вызван после завершения анимации. Этот метод должен принимать три параметра в следующем порядке:
1) идентификатор анимации типа NSString: здесь будет содержаться идентификатор анимации, передаваемый с началом анимации методу класса beginAnimations: context:, относящемуся к классу UIView;
2) индикатор «завершения» типа NSNumber: этот параметр содержит в NSNumber логическое значение. Среда времени исполнения устанавливает его в YES, если анимация была остановлена в коде, не успев полностью завершиться. Если это значение равно NO, то это означает, что анимация была без перерывов воспроизведена до самого конца;
3) контекст типа void *: это контекст, который с началом анимации передается методу класса beginAnimations: context:, относящемуся к классу UIView.
• setAnimationWillStartSelector: – задает селектор, который должен быть вызван в объекте делегата перед самым началом анимации. Селектор, передаваемый этому методу класса, должен иметь два параметра в таком порядке:
1) идентификатор анимации типа NSString: среда времени исполнения задает для этого параметра значение идентификатора анимации, передаваемого с началом анимации методу класса beginAnimations: context:, относящемуся к классу UIView;
2) контекст типа void *: это контекст, который с началом анимации был передан методу класса beginAnimations: context:, относящемуся к классу UIView.
• setAnimationDelay: – задает задержку для анимации (в секундах) перед ее началом. Например, если это значение установлено в 3.0f, то анимация будет начинаться через 3 секунды после выполнения этого метода.
• setAnimationRepeatCount: – указывает количество прогонов анимации, которые должны быть выполнены в блоке кода.
Теперь, когда нам известны наиболее полезные методы класса UIView, помогающие анимировать виды, рассмотрим другую анимацию. В этом примере кода я создам два вида с изображениями (в каждом из них будет показано одно и то же изображение), и они появятся на экране в одно и то же время, одно в левом верхнем углу, другое – в правом нижнем (рис. 17.35).
Рис. 17.35. Исходное положение, с которого начинается анимация
В этом примере изображение из верхнего левого угла будет называться image 1, а из правого нижнего – image 2.
Как уже упоминалось, в этом коде мы собираемся создать два изображения, в верхнем левом и правом нижнем углах. Далее image 1 станет двигаться по направлению к image 2 и будет так перемещаться на протяжении 3 секунд, а потом медленно исчезнет. Когда image 1 начнет движение, станет двигаться и image 2 – оно пойдет в верхний левый угол экрана, где изначально находилось изображение image 1. Опять же мы хотим, чтобы анимация изображения image 2 завершилась за 3 секунды и оно медленно исчезло. Когда вы запустите этот код на устройстве или симуляторе iOS, такая анимация будет выглядеть очень классно. Теперь расскажу, как все это запрограммировать.
1. В верхней части. m-файла нашего контроллера вида определим два вида с изображениями:
@interface ViewController ()
@property (nonatomic, strong) UIImageView *xcodeImageView1;
@property (nonatomic, strong) UIImageView *xcodeImageView2;
@end
@implementation ViewController
2. В методе экземпляра viewDidLoad, относящемся к контроллеру вашего вида, инициализируем оба этих вида с изображениями и помещаем их в основной вид:
– (CGRect) bottomRightRect{
CGRect endRect;
endRect.origin.x = self.view.bounds.size.width – 100;
endRect.origin.y = self.view.bounds.size.height – 100;
endRect.size = CGSizeMake(100.0f, 100.0f);
return endRect;
}
– (void) viewDidLoad{
[super viewDidLoad];
UIImage *xcodeImage = [UIImage imageNamed:@"Xcode.png"];
self.xcodeImageView1 = [[UIImageView alloc]
initWithImage: xcodeImage];
self.xcodeImageView2 = [[UIImageView alloc]
initWithImage: xcodeImage];
/* Просто задаем размеры так, чтобы изображения уменьшились. */
[xcodeImageView1 setFrame: CGRectMake(0.0f,
0.0f,
100.0f,
100.0f)];
[self.xcodeImageView2 setFrame: [self bottomRightRect]];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview: self.xcodeImageView1];
[self.view addSubview: self.xcodeImageView2];
}
3. Реализуем для нашего контроллера вида метод экземпляра, который называется startTopLeftImageViewAnimation. Как понятно из названия[12]12
StartTopLeft (англ.) – «начинаем с верхнего левого угла», ImageView (англ.) – «вид с изображением», Animation (англ.) – «анимация». – Примеч. пер.
[Закрыть], данный метод будет выполнять анимацию для изображения image 1, перемещая его из верхнего левого угла экрана в нижний правый, а изображение тем временем будет медленно исчезать. Такое исчезновение достигается установкой альфа-значения в 0:
– (void) startTopLeftImageViewAnimation{
/* Начинаем с верхнего левого угла. */
[self.xcodeImageView1 setFrame: CGRectMake(0.0f,
0.0f,
100.0f,
100.0f)];
[self.xcodeImageView1 setAlpha:1.0f];
[UIView beginAnimations:@"xcodeImageView1Animation"
context:(__bridge void *)self.xcodeImageView1];
/* Трехсекундная анимация */
[UIView setAnimationDuration:3.0f];
/* Получаем анимационные делегаты. */
[UIView setAnimationDelegate: self];
[UIView setAnimationDidStopSelector:
@selector(imageViewDidStop: finished: context:)];
/* Заканчиваем в нижнем правом углу. */
[self.xcodeImageView1 setFrame: CGRectMake(220.0f,
350.0f,
100.0f,
100.0f)];
[self.xcodeImageView1 setAlpha:0.0f];
[UIView commitAnimations];
}
4. Когда анимация какого-либо из этих видов остановится, мы удалим данный вид из иерархии родительских видов, так как больше в нем не нуждаемся. Как было показано в методе startTopLeftImageViewAnimation, мы передали селектор делегата методу класса setAnimationDidStopSelector:, относящемуся к классу UIView. Этот селектор будет вызываться после окончания анимации image 1 (как было показано ранее) и image 2 (как мы вскоре увидим). Вот реализация этого селектора делегата:
– (void)imageViewDidStop:(NSString *)paramAnimationID
finished:(NSNumber *)paramFinished
context:(void *)paramContext{
UIImageView *contextImageView = (__bridge UIImageView *)paramContext;
[contextImageView removeFromSuperview];
}
5. Кроме того, нам понадобится метод для анимирования image 2. Между написанием анимационных методов для image 2 и image 1 есть небольшая разница. Я хочу начать анимацию image 2, немного не дожидаясь завершения анимации image 1. Следовательно, если анимация image 1 завершается за 3 секунды, то я начну анимировать image 2 со второй секунды анимации image 1. Таким образом, анимация image 2 начнется еще до того, как изображение image 1 дойдет до нижнего правого угла экрана и исчезнет. Чтобы достичь такого результата, я установлю начало анимации для обоих изображений на одно и то же время, но перед началом анимации image 2 поставлю двухсекундную задержку. Итак, если обе анимации начнутся в час дня, то для изображения image 1 начальным моментом анимации будет 13:00:00, а конечным – 13:00:03. Соответствующие значения image 2 будут равны 13:00:02 и 13:00:05. Вот как будет происходить анимация image 2:
– (void) startBottomRightViewAnimationAfterDelay:(CGFloat)paramDelay{
/* Начинаем с нижнего правого угла. */
[self.xcodeImageView2 setFrame: [self bottomRightRect]];
[self.xcodeImageView2 setAlpha:1.0f];
[UIView beginAnimations:@"xcodeImageView2Animation"
context:(__bridge void *)self.xcodeImageView2];
/* Трехсекундная анимация */
[UIView setAnimationDuration:3.0f];
[UIView setAnimationDelay: paramDelay];
/* Получаем анимационные делегаты. */
[UIView setAnimationDelegate: self];
[UIView setAnimationDidStopSelector:
@selector(imageViewDidStop: finished: context:)];
/* Заканчиваем в верхнем левом углу. */
[self.xcodeImageView2 setFrame: CGRectMake(0.0f,
0.0f,
100.0f,
100.0f)];
[self.xcodeImageView2 setAlpha:0.0f];
[UIView commitAnimations];
}
6. И последнее, но немаловажное замечание. Как только вид отобразится, мы должны запустить методы startTopLeftImageViewAnimation и startBottomRightViewAnimationAfterDelay::
– (void) viewDidAppear:(BOOL)paramAnimated{
[super viewDidAppear: paramAnimated];
[self startTopLeftImageViewAnimation];
[self startBottomRightViewAnimationAfterDelay:2.0f];
}
Правообладателям!
Это произведение, предположительно, находится в статусе 'public domain'. Если это не так и размещение материала нарушает чьи-либо права, то сообщите нам об этом.