Обсуждение

Обсуждение

В разделе 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.

Данный текст является ознакомительным фрагментом.



Поделитесь на страничке

Следующая глава >

Похожие главы из других книг:

Обсуждение

Из книги автора

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


Обсуждение

Из книги автора

Обсуждение Фреймворк Assets Library — удобный посредник между разработчиком и библиотекой фотографий. Как будет указано в разделе 13.6, в iOS SDK вам предоставляются встроенные компоненты графического пользовательского интерфейса, которыми можно пользоваться для доступа к


Обсуждение

Из книги автора

Обсуждение Чтобы пользователь мог выбирать фотоснимки или видеоролики из своей библиотеки фотографий, необходимо установить свойство sourceType экземпляра UIImagePickerController в значение UIImagePickerControllerSourceTypePhotoLibrary и только потом открывать перед пользователем инструмент для выбора


Обсуждение

Из книги автора

Обсуждение Библиотека ресурсов подразделяется на группы. В каждой группе содержатся ресурсы, а каждый ресурс имеет свойства, например URL (универсальные локаторы ресурсов) и объекты представления.Все ресурсы всех типов можно получать из библиотеки ресурсов с помощью


Обсуждение

Из книги автора

Обсуждение Класс UIVideoEditorController, содержащийся в iOS SDK, позволяет программисту вывести на экран перед пользователем специальный интерфейс для редактирования. Все, что требуется сделать, — предоставить URL видеоролика, который предполагается отредактировать, а потом


Обсуждение

Из книги автора

Обсуждение В зависимости от того, на работу в какой версии iOS рассчитано ваше приложение, его можно запускать и выполнять на различных устройствах, где установлены разные версии iOS. Например, вы можете разрабатывать приложение в последней версии iOS SDK, но в качестве целевой


Обсуждение

Из книги автора

Обсуждение Когда приложение переходит в фоновый режим, работа его основного потока приостанавливается. Потоки, которые вы создаете в своем приложении с помощью метода класса detachNewThreadSelector: toTarget: withObject:, относящегося к классу NSThread, также приостанавливаются. Если вы


Обсуждение

Из книги автора

Обсуждение Многие приложения, ежедневно поступающие на рынок App Store, обладают возможностями соединения с теми или иными серверами. Некоторые выбирают с сервера данные для обновления, другие отсылают информацию на сервер и т. д. В течение долгого времени в iOS существовал


Обсуждение

Из книги автора

Обсуждение В iOS приложение может запросить продолжить воспроизведение своих аудиофайлов, даже если оно само переходит в фоновый режим. В этом разделе мы воспользуемся плеером AVAudioPlayer, который прост и удобен в обращении. Наша задача — запустить аудиоплеер и воспроизвести


Обсуждение

Из книги автора

Обсуждение Когда приложение работает в приоритетном режиме, можно получать от экземпляра CLLocationManager делегатные сообщения, информирующие вас о том, что iOS обнаружила перемещение устройства на новое место. Однако если приложение переходит в фоновый режим и становится


Обсуждение

Из книги автора

Обсуждение Допустим, пустое приложение iOS (то есть приложение всего с одним окном, для которого еще не написан код) впервые запускается на устройстве с iOS, поддерживающем работу в многозадачном режиме. Оно запускается именно впервые, а не возвращается из фонового режима в


Обсуждение

Из книги автора

Обсуждение При работе с приложениями, которые используют класс NSURLConnection, но, уходя в фоновый режим, не запрашивают у iOS дополнительного времени, обращаться с соединениями не составляет никакого труда. Рассмотрим на примере, как будет действовать асинхронное соединение,


Обсуждение

Из книги автора

Обсуждение Пока ваше приложение работает в фоновом режиме, может произойти многое! Например, пользователь может вдруг изменить локализацию устройства с iOS на странице Settings (Настройки) и задать, к примеру, испанский язык вместо английского. Приложения могут


Обсуждение

Из книги автора

Обсуждение В приложениях, написанных для iOS, файл пакета настроек может быть предоставлен пользователю для внесения собственных настроек. Эти настройки будут доступны пользователю в приложении (Settings) на устройстве. Чтобы лучше понять, как работает этот механизм,


Обсуждение

Из книги автора

Обсуждение Пуш-уведомления похожи на локальные уведомления тем, что позволяют сообщать пользователю определенную информацию, даже если ваше приложение неактивно при поступлении уведомления. В то время как локальные уведомления назначаются самим приложением,