В этом уроке мы рассмотрим некоторые расширенные функции и шаблоны использования скромного класса UIImage
в iOS. К концу этого урока вы узнаете следующее: как создавать изображения в коде, как создавать изображения с изменяемым размером для элементов пользовательского интерфейса, таких как выноски, и как создавать анимированные изображения.
Теоретический обзор
Если вам когда-либо приходилось отображать изображение в приложении для iOS, вы, вероятно, знакомы с UIImage
. Это класс, который позволяет вам представлять изображения на iOS. На сегодняшний день это наиболее распространенный способ использования UIImage
и он довольно прост: у вас есть файл изображения в одном из нескольких стандартных форматов изображений (PNG, JPEG, BMP и т. Д.), И вы хотите отобразить его в интерфейсе вашего приложения. Вы UIImage
новый экземпляр UIImage
, отправляя сообщение класса imageNamed:
Если у вас есть экземпляр UIImageView
, вы можете установить его свойство image
для экземпляра UIImage
, а затем вы можете вставить представление изображения в свой интерфейс, настроив его как подпредставление для вашего экранного представления:
1
2
3
4
|
UIImage *img = [UIImage imageNamed:filename];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
// Set frame, etc. …
[self.view addSubview:imgView];
|
Вы также можете выполнить эквивалент вышеописанной процедуры непосредственно в Интерфейсном Разработчике.
Есть несколько других способов создания экземпляра изображения, например, из URL-адреса или из архивированного изображения, которое было сохранено как тип NSData
, но мы не будем фокусироваться на этих аспектах в этом руководстве.
Прежде чем говорить о создании изображений в коде, напомним, что на самом примитивном уровне мы знаем, что на самом деле представляет собой двумерное изображение: двумерный массив значений пикселей. Область памяти, представляющая массив пикселей для изображения, часто называют его хранилищем растровых изображений . Это иногда полезно иметь в виду, когда речь идет о памяти. Однако важно понимать, что UIImage
— это действительно абстракция более высокого уровня изображения, чем у массива пикселей, и оптимизированная в соответствии с требованиями и сценариями использования мобильной платформы. Хотя теоретически возможно создать изображение, заполнив весь массив пикселей значениями, или получить доступ к растровому изображению существующего изображения и прочитать или изменить значение отдельного пикселя, это довольно неудобно делать в iOS и на самом деле это не так. облегчается API. Однако, поскольку большинство разработчиков приложений редко испытывают реальную необходимость связываться с изображениями на уровне пикселей, обычно это не проблема.
Что UIImage
(или, в более общем смысле, UIKit и Core Graphics ), так это создание нового изображения путем наложения существующих изображений интересными способами или создание изображения путем растеризации векторного рисунка, созданного с UIBezierPath
класса UIBezierPath
или Основные графические функции CGPath...
Если вы хотите написать приложение, которое позволяет пользователю создавать коллаж из своих изображений, это легко сделать с помощью UIKit и UIImage
. Если вы разработали, скажем, приложение для рисования от руки и хотите, чтобы пользователь сохранил свое творение, тогда самый простой подход будет включать извлечение UIImage
из контекста рисования. В первом разделе этого руководства вы узнаете, как можно реализовать обе эти идеи!
Важно помнить, что UIImage
таким образом, ничем не отличается от изображения, полученного путем открытия изображения из фотоальбома или загрузки из Интернета: его можно сохранить в архиве, загрузить в фотоальбом или отобразить в UIImageView
.
Изменение размера изображения является важным типом манипуляции изображения. Очевидно, что вы хотели бы избежать увеличения изображения, поскольку это приводит к ухудшению качества и резкости изображения. Тем не менее, существуют определенные сценарии, в которых необходимы изменяемые размеры изображений, и на самом деле есть разумные способы сделать это, которые не ухудшают качество изображения. UIImage
обслуживает эту ситуацию, разрешая изображениям, которые имеют внутреннюю область с изменяемым размером и «вставки краев» на границах изображения, которые изменяют размеры в определенном направлении или не изменяют размеры вообще. Кроме того, изменение размера может быть выполнено либо путем наложения плитки, либо растяжения изменяемых размеров частей для двух несколько разных эффектов, которые могут быть полезны в различных ситуациях.
Вторая часть раздела реализации покажет конкретную реализацию этой идеи. Мы напишем изящный маленький класс, который может отображать любое количество текста внутри изменяемого размера изображения!
Наконец, мы немного поговорим об анимации изображений с помощью UIImage
. Как вы, вероятно, можете догадаться, это означает «последовательное воспроизведение» серии изображений, порождающих иллюзию анимации, очень похожую на анимированные GIF-изображения, которые вы видите в Интернете. Хотя это может показаться немного ограниченным, в простых ситуациях UIImage
анимированных изображений в UIImage
может быть именно тем, что вам нужно, и все, что вам нужно, — это несколько строк кода для запуска и запуска. Это то, что мы рассмотрим в третьем и последнем разделе этого урока! Время засучить рукава и приступить к работе!
1. Начало нового проекта
Создайте новый проект iOS в Xcode с шаблоном « Пустое приложение ». Назовите это «UIImageFun» . Установите флажок «Автоматический подсчет ссылок», но снимите флажки «Основные данные» и «Юнит тесты».
Небольшое примечание, прежде чем мы продолжим: в этом руководстве используются несколько наборов изображений, и для их получения вам нужно щелкнуть там, где написано «Скачать исходные файлы» в верхней части этой страницы. После загрузки и разархивирования архива перетащите папку с именем «Изображения» в Навигатор проекта — крайнюю левую вкладку на левой панели в Xcode. Если левая панель не видна, нажмите комбинацию клавиш ⌘ + 0, чтобы сделать ее видимой, и убедитесь, что выбрана крайняя левая вкладка, значок которой выглядит как папка.
Загруженный файл также содержит полный проект Xcode с изображениями, уже добавленными в проект, на случай, если вы застряли где-нибудь.
2. Создание изображения в коде
Создайте новый файл для класса Objective C, назовите его ViewController
и сделайте его подклассом UIViewController
. Убедитесь, что параметры, относящиеся к iPad и XIB, не отмечены.
Замените весь код в ViewController.m следующим:
01
02
03
04
05
06
07
08
09
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#import «ViewController.h»
@interface ViewController ()
{
UIImage *img;
UIImageView *iv;
NSMutableArray *ivs;
}
@end
@implementation ViewController
— (void)viewDidLoad
{
[super viewDidLoad];
// (1) Creating a bitmap context, filling it with yellow as «background» color:
CGSize size = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height);
UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0);
[[UIColor yellowColor] setFill];
UIRectFill(CGRectMake(0, 0, size.width, size.height));
// (2) Create a circle via a bezier path and stroking+filling it in the bitmap context:
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(size.width/2, size.height/2) radius:140 startAngle:0 endAngle:2 * M_PI clockwise:YES];
[[UIColor blackColor] setStroke];
bezierPath.lineWidth = 5.0;
[bezierPath stroke];
[[UIColor redColor] setFill];
[bezierPath fill];
// (3) Creating an array of images:
NSArray *rocks = @[[UIImage imageNamed:@»rock1″],
[UIImage imageNamed:@»rock2″],
[UIImage imageNamed:@»rock3″],
[UIImage imageNamed:@»rock4″],
[UIImage imageNamed:@»rock5″],
[UIImage imageNamed:@»rock6″],
[UIImage imageNamed:@»rock7″],
[UIImage imageNamed:@»rock8″],
[UIImage imageNamed:@»rock9″]];
// (4) Drawing rocks in a loop, each chosen randomly from the image set and drawn at a random position in a circular pattern:
for ( int i = 0; i < 100; i++)
{
int idx = arc4random() % rocks.count;
NSLog(@»idx = %d», idx);
int radius = 100;
int revolution = 360;
float r = (float)(arc4random() % radius);
float angle = (float)(arc4random() % revolution);
float x = size.width/2 + r * cosf(angle * M_PI/180.0);
float y = size.height/2 + r * sinf(angle * M_PI/180.0);
CGSize rockSize = ((UIImage *)rocks[idx]).size;
[rocks[idx] drawAtPoint:CGPointMake(x-rockSize.width/2, y-rockSize.height/2)];
}
// (5) Deriving a new UIImage instance from the bitmap context:
UIImage *fImg = UIGraphicsGetImageFromCurrentImageContext();
// (6) Closing the context:
UIGraphicsEndImageContext();
// (7) Setting the image view’s image property to the created image, and displaying
iv = [[UIImageView alloc] initWithImage:fImg];
[self.view addSubview:iv];
}
@end
|
Настройте делегат приложения для использования экземпляра ViewController
в качестве корневого контроллера представления, заменив код в AppDelegate.m следующим:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
#import «AppDelegate.h»
#import «ViewController.h»
@implementation AppDelegate
— (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[ViewController alloc] init];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
@end
|
Давайте рассмотрим код для viewDidLoad:
где происходит все действие. Мы будем ссылаться на цифры в контексте кода.
- Мы хотим начать с рисования изображения, а это значит, что нам нужен «холст». В правильной терминологии это называется контекстом изображения (или контекстом растрового изображения). Мы создаем его, вызывая
UIGraphicsBeginImageContextWithOptions()
. Эта функция принимает в качестве аргументовCGSize
, для которого мы установили размер представления нашего контроллера представления, то есть весь экран.BOOL
говорит нам, является ли контекст непрозрачным или нет. Непрозрачный контекст более эффективен, но вы не можете «видеть сквозь» его. Поскольку в нашем контексте нет ничего интересного, мы установили его наYES
. Коэффициент масштабирования, который представляет собой число сfloat
которое мы устанавливаем равным 0,0 (значение, которое обеспечивает масштаб для конкретного устройства). В зависимости от того, имеет ли устройство дисплей Retina, коэффициент масштабирования будет установлен на 2,0 или 1,0 соответственно. Вскоре я расскажу немного больше о масштабном коэффициенте, но для всестороннего обсуждения я отошлю вас к официальной документации (в частности, к разделу «Точки против пикселей» в Руководстве по рисованию и печати для iOS ).Как только мы создаем контекст изображения таким образом, он становится текущим контекстом . Это важно, потому что для рисования с помощью UIKit у нас должен быть текущий контекст рисования, где происходит все неявное рисование. Теперь мы устанавливаем цвет заливки для текущего контекста и заполняем прямоугольник размером всего контекста.
-
Теперь мы создаем экземпляр
UIBezierPath
в форме круга, которыйUIBezierPath
толстым контуром и заливаем другим цветом. На этом мы завершаем рисование нашего изображения. - Мы создаем массив изображений, каждый экземпляр которого
imageNamed:
помощьюimageNamed:
initializerUIImage
. Здесь важно отметить, что у нас есть два набора изображений горных пород: rock1.png, rock2.png, … и [email protected], [email protected] , причем последнее в два раза больше разрешения первого. Одной из замечательных особенностейUIImage
является то, что во время выполнения методimageNamed:
автоматически ищет изображение с суффиксом @ 2x, предположительно двойного разрешения, на устройстве Retina. Если таковой имеется, он используется! Если изображение с суффиксом отсутствует или если устройство не Retina, используется стандартное изображение. Обратите внимание, что мы не указываем суффикс изображения в инициализаторе. Использование изображений с одинарным и двойным разрешением в сочетании с масштабом, зависящим от устройства (в результате установкиscale
на0.0
), гарантирует, что фактический размер объектов на экране будет одинаковым. Естественно, изображения Retina будут более четкими из-за более высокой плотности пикселей. - Мы формируем наше изображение в цикле, помещая случайно выбранный камень из нашего набора изображений в случайную точку (ограниченную кругом) на каждой итерации. Метод
UIImage
drawAtPoint:
рисует выбранное изображение скалы в указанной точке в текущий контекст изображения. - Теперь мы извлекаем новый объект
UIImage
из содержимого текущего контекста изображения, вызываяUIGraphicsGetImageFromCurrentImageContext()
. - Вызов
UIGraphicsEndImageContext()
завершает текущий контекст изображения и очищает память. - Наконец, мы устанавливаем изображение, которое мы создали, как свойство
image
нашегоUIImageView
и отображаем его на экране.
Сборка и запуск. Вывод должен выглядеть следующим образом, только случайным образом по-разному:
Тестируя устройства Retina и устройства, не относящиеся к Retina, или изменив тип устройства в имитаторе в меню « Оборудование» , вы можете убедиться, что камни перевернуты друг относительно друга. Еще раз, я сделал это только для того, чтобы мы могли легко подтвердить, что правильный набор изображений будет выбран во время выполнения. Как правило, у вас нет причин делать это!
Напомним, что, рискуя осмыслить точку, мы создали новое изображение (объект UIImage
), UIImage
вместе изображения, которые у нас уже есть, поверх рисунка, который мы нарисовали.
Перейдем к следующей части реализации!
3. Изменяемые размеры изображений
Посмотрите на рисунок ниже.
Левое изображение показывает выноску или « речевой пузырь », похожий на тот, который можно увидеть во многих приложениях обмена сообщениями. Очевидно, что мы хотели бы, чтобы выноска расширялась или уменьшалась в зависимости от объема текста в ней. Кроме того, мы хотели бы использовать одно изображение, из которого мы можем генерировать выноски любого размера. Если мы увеличиваем весь выноски одинаково во всех направлениях, все изображение становится пиксельным или размытым в зависимости от используемого алгоритма изменения размера. Однако обратите внимание на то, как было разработано изображение выноски. Его можно расширить в определенных направлениях без потери качества, просто реплицируя пиксельные элементы по мере продвижения. Размеры углов не могут быть изменены без изменения качества изображения, но, с другой стороны, середина — это просто блок пикселей одинакового цвета, который можно сделать любого размера, который нам нравится. Верхнюю и нижнюю стороны можно растягивать по горизонтали без потери качества, а левую и правую стороны по вертикали. Все это показано на рисунке справа.
К счастью для нас, в UIImage
есть несколько методов для создания изображений такого UIImage
с UIImage
. Мы будем использовать resizableImageWithCapInsets:
Здесь « вставки цоколя » представляют размеры нерастягиваемых углов изображения (начиная с верхнего поля и перемещаясь против часовой стрелки) и инкапсулированы в struct
типа UIEdgeInsets
состоящую из четырех UIEdgeInsets
с float
:
1
2
3
|
typedef struct {
float top, left, bottom, right;
} UIEdgeInsets;
|
На рисунке ниже следует уточнить, что представляют собой эти цифры:
Давайте воспользуемся изменяемым UIImage
чтобы создать простой класс, который позволяет нам заключать любое количество текста в изменяемое изображение!
Создайте подкласс NSObject
именем Note
и введите следующий код в Note.h и Note.m соответственно.
01
02
03
04
05
06
07
08
09
10
11
|
#import <Foundation/Foundation.h>
@interface Note : NSObject
@property (nonatomic, readonly) NSString *text;
@property (nonatomic, readonly) UIImageView *noteView;
— (id)initWithText:(NSString *)text fontSize:(float)fontSize noteChrome:(UIImage *)img edgeInsets:(UIEdgeInsets)insets maximumWidth:(CGFloat)width topLeftCorner:(CGPoint)corner;
@end
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#import «Note.h»
@implementation Note
— (id)initWithText:(NSString *)text fontSize:(float)fontSize noteChrome:(UIImage *)img edgeInsets:(UIEdgeInsets)insets maximumWidth:(CGFloat)width topLeftCorner:(CGPoint)corner
{
if (self = [super init])
{
#define LARGE_NUMBER 10000 // just a large (but arbitrary) number because we don’t want to impose any vertical constraint on our note size
_text = [NSString stringWithString:text];
CGSize computedSize = [text sizeWithFont:[UIFont systemFontOfSize:fontSize] constrainedToSize:CGSizeMake(width, LARGE_NUMBER) lineBreakMode:NSLineBreakByWordWrapping];
UILabel *textLabel = [[UILabel alloc] init];
textLabel.font = [UIFont systemFontOfSize:fontSize];
textLabel.text = self.text;
textLabel.numberOfLines = 0;
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.frame = CGRectMake(insets.left, insets.top, computedSize.width , computedSize.height);
_noteView = [[UIImageView alloc] initWithFrame:CGRectMake(corner.x, corner.y, textLabel.bounds.size.width+insets.left+insets.right, textLabel.bounds.size.height+insets.top+insets.bottom)];
_noteView.image = [img resizableImageWithCapInsets:insets];
[_noteView addSubview:textLabel];
}
return self;
}
@end
|
Метод инициализатора для Note
, -initWithText:fontSize: noteChrome:edgeInsets:maximumWidth:topLeftCorner:
принимает несколько параметров, включая отображаемую текстовую строку, размер шрифта, заметку «хром» (которая представляет собой изменяемый размер UIImage
который будет окружать текст), вставки заглавных букв, максимальная ширина, которую может иметь вид изображения заметки, и верхний левый угол рамки заметки.
После инициализации свойство noteView
класса noteView
(типа UIImageView
) является элементом пользовательского интерфейса, который мы будем отображать на экране.
Реализация довольно проста. Мы используем очень полезный метод из категории NSString
в UIKit , sizeWithFont:constrainedToSize:lineBreakMode:
который вычисляет размер, который блок текста займет на экране, при определенных параметрах. После этого мы создаем текстовую метку ( UILabel
) и заполняем ее предоставленным текстом. Принимая во внимание размеры вставки и вычисленный размер текста, мы назначаем метке соответствующий кадр, а также делаем изображение нашего noteView
достаточно большим (с помощью метода resizableImageWithCapInsets
), чтобы метка удобно noteView
поверх внутренней области. изображения.
На рисунке ниже изображение слева показывает, как будет выглядеть типичная заметка, содержащая несколько строк текста.
Обратите внимание, что интерьер не имеет ничего интересного. На самом деле мы можем «обрезать» изображение до минимума (как показано справа), избавившись от всех пикселей внутри с помощью программного обеспечения для редактирования изображений. Фактически, в документации Apple рекомендует, чтобы для лучшей производительности внутренняя область была выложена плиткой 1 x 1 пиксель. Это то, что представляет собой забавное маленькое изображение справа, и это то, что мы собираемся передать нашему инициализатору Note
. Убедитесь, что он был добавлен в ваш проект как squeezednote.png, когда вы перетаскивали папку Images в свой проект.
В ViewController.m
введите оператор #import "Note.h"
вверху. Закомментируйте предыдущую форму viewDidLoad:
и введите следующее:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
— (void)viewDidLoad
{
[super viewDidLoad];
NSString *text1 = @»Hi!»;
NSString *text2 = @»I size myself according to my content!»;
NSString *text3 = @»Standard boring random text: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.»;
UIImage *noteChrome = [UIImage imageNamed:@»squeezednote»];
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(37, 12, 12, 12);
Note *note1 = [[Note alloc] initWithText:text1 fontSize:25.0 noteChrome:noteChrome edgeInsets:edgeInsets maximumWidth:300 topLeftCorner:CGPointMake(10, 10)];
Note *note2 = [[Note alloc] initWithText:text2 fontSize:30.0 noteChrome:noteChrome edgeInsets:edgeInsets maximumWidth:300 topLeftCorner:CGPointMake(200, 10)];
Note *note3 = [[Note alloc] initWithText:text3 fontSize:16.0 noteChrome:noteChrome edgeInsets:edgeInsets maximumWidth:300 topLeftCorner:CGPointMake(10, 200)];
[self.view addSubview:note1.noteView];
[self.view addSubview:note2.noteView];
[self.view addSubview:note3.noteView];
}
|
Мы просто создаем объекты Note
с другим объемом текста. Создайте, запустите и наблюдайте, насколько хорошо «хром» вокруг заметки изменяет размеры, чтобы разместить текст внутри ее границ.
Для сравнения, вот как будет выглядеть вывод, если » squeezednote.png » будет настроен как «обычный» UIImage
с помощью imageNamed:
и imageNamed:
размер одинаково во всех направлениях.
Следует признать, что на самом деле мы бы не использовали «минимальное» изображение, такое как «squeezednote», если бы мы не использовали изображения с изменяемым размером в первую очередь, поэтому эффект, показанный на предыдущем скриншоте, сильно преувеличен. Тем не менее, проблема размывания определенно будет там.
К финальной части урока!
4. Анимированные картинки
Под анимированным изображением я имею в виду последовательность отдельных 2D-изображений, которые отображаются последовательно. Это в основном только спрайт-анимация, которая используется в большинстве 2D-игр. UIImage
имеет метод инициализатора animatedImageNamed:duration:
которому вы передаете строку, представляющую префикс последовательности изображений для анимации, поэтому если ваши изображения называются «robot1.png», «robot2.png», …, «robot60.png» , вы просто передаете строку «robot» этому методу. Продолжительность анимации также передается. Вот и все! Когда изображение добавляется в UIImageView
, оно непрерывно анимируется на экране. Давайте реализуем пример.
Закомментируйте предыдущую версию viewDidLoad:
и введите следующую версию.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
— (void)viewDidLoad
{
[super viewDidLoad];
ivs = [NSMutableArray array];
img = [UIImage animatedImageNamed:@»explosion» duration:2.0];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(explosion:)];
[self.view addGestureRecognizer:tap];
}
— (void)explosion:(UITapGestureRecognizer *)t
{
CGPoint loc = [t locationInView:self.view];
for (UIImageView *v in ivs)
{
if ([v pointInside:[v convertPoint:loc fromView:self.view] withEvent:nil])
{
[ivs removeObject:v];
[v removeFromSuperview];
return;
}
}
UIImageView *v = [[UIImageView alloc] initWithImage:img];
v.center = loc;
[ivs addObject:v];
[self.view addSubview:v];
}
|
Мы добавили набор PNG-изображений в наш проект, взрывами от1.png через explo81.png, которые представляют собой анимационную последовательность огненного взрыва. Наш код довольно прост. Мы обнаруживаем касание на экране и либо помещаем новую анимацию взрыва в точку касания, либо, если в этой точке уже произошел взрыв, мы удаляем его. Обратите внимание, что основной код состоит из простого создания анимированного изображения с помощью animatedImageNamed:
которому мы передаем строку @"explosion"
и значение с плавающей точкой на время.
Вам нужно будет запустить приложение на симуляторе или на устройстве самостоятельно, чтобы насладиться фейерверком, но вот изображение, которое захватывает один кадр действия с несколькими взрывами, происходящими одновременно.
Следует признать, что если вы разрабатывали динамичную игру-экшн, такую как стрелялка или платформер с боковой прокруткой, то поддержка анимированных изображений в UIImage
могла бы показаться довольно примитивной. Они не будут вашим подходом для реализации анимации. Это не совсем то, для UIImage
построен UIImage
, но в других, менее требовательных сценариях, это может быть просто билет! Поскольку анимация выполняется непрерывно до тех пор, пока вы не удалите анимированное изображение или представление изображения из интерфейса, вы можете остановить анимацию через заданный интервал времени, отправив отложенное сообщение с помощью – performSelector:withObject:afterDelay:
или используя NSTimer
.
Вывод
В этом руководстве мы рассмотрели некоторые полезные, но менее известные функции класса UIImage
которые могут пригодиться. Я предлагаю вам взглянуть на UIImage
Class Reference, потому что некоторые функции, которые мы обсуждали в этом руководстве, имеют больше опций. Например, изображения могут быть составлены с использованием одного из нескольких вариантов наложения . Изменяемые размеры изображений могут быть настроены в одном из двух режимов изменения размера : мозаичного (который мы использовали неявно) или растяжения. Даже анимированные изображения могут иметь вставки. Мы не говорили о базовом непрозрачном типе UIImage
оборачивает UIImage
. Вам нужно иметь дело с CGImage
если вы программируете на уровне Core Graphics , который является API на основе C, который находится на один уровень ниже UIKit в платформе iOS. Core Graphics более мощный, чем UIKit для программирования, но не так просто. Мы также не говорили об изображениях, созданных с данными из объекта Core Image , так как это было бы более целесообразно в учебнике по Core Image .
Я надеюсь, что вы нашли этот урок полезным. Продолжайте кодировать!