Обсуждение

Обсуждение

В Core Graphics рисовать тени не составляет никакого труда. Графический контекст — это и есть элемент, несущий на себе тень. Это означает, что от вас требуется просто применить тень к контексту, отрисовать для нее необходимые контуры, а потом удалить тень с контекста (или задать новый контекст). Чуть позже мы рассмотрим эти операции на примере.

В Core Graphics для применения тени к графическому контексту могут использоваться две процедуры:

• CGContextSetShadow — создает черные или серые тени, принимает три параметра:

• графический контекст, к которому следует применить тень;

• отступ, указываемый значением типа CGSize, на который тень распространяется вправо и вниз от каждой фигуры. Чем больше значение x данного отступа, тем больше тень будет распространяться вправо. Чем больше значение y, тем ниже будет тень;

• значение размытия, которое следует применить к тени, указывается как число с плавающей точкой (CGFloat). Если задать для данного параметра значение 0.0f, то у тени будут абсолютно четкие контуры. Чем выше это значение, тем более размытой будет становиться тень. Далее будет приведен соответствующий пример;

• CGContextSetShadowWithColor — принимает такие же параметры, как и CGContextSetShadow, плюс еще один. Этот четвертый параметр типа CGColorRef задает цвет тени.

В начале этого подраздела я отмечал, что графический контекст сохраняет свойства расположенных в нем теней, пока мы специально не удалим тень. Хотелось бы дополнительно разъяснить этот момент на примере. Напишем код, позволяющий нам отрисовать два прямоугольника: первый с тенью, второй — без нее. Первый прямоугольник нарисуем так:

— (void) drawRectAtTopOfScreen{

/* Получаем описатель для актуального контекста. */

CGContextRef currentContext = UIGraphicsGetCurrentContext();

CGContextSetShadowWithColor(currentContext,

CGSizeMake(10.0f, 10.0f),

20.0f,

[[UIColor grayColor] CGColor]);

/* Сначала создаем путь. Просто описатель пути. */

CGMutablePathRef path = CGPathCreateMutable();

/* Это границы прямоугольника. */

CGRect firstRect = CGRectMake(55.0f,

60.0f,

150.0f,

150.0f);

/* Добавляем прямоугольник к пути. */

CGPathAddRect(path,

NULL,

firstRect);

/* Добавляем путь к контексту. */

CGContextAddPath(currentContext,

path);

/* Задаем голубой в качестве цвета заливки. */

[[UIColor colorWithRed:0.20f

green:0.60f

blue:0.80f

alpha:1.0f] setFill];

/* Заполняем путь в контексте цветом заливки. */

CGContextDrawPath(currentContext,

kCGPathFill);

/* Избавляемся от пути. */

CGPathRelease(path);

}

— (void) drawRect:(CGRect)rect{

[self drawRectAtTopOfScreen];

}

Если вызвать этот метод в методе экземпляра drawRect: объекта-вида, то на экране появится прямоугольник с красивой тенью, как мы и хотели (рис. 17.24).

Рис. 17.24. Тень, примененная к прямоугольнику

Теперь нарисуем второй прямоугольник. Мы не будем специально запрашивать тень, а оставим свойство тени графического контекста таким же, как и в первом прямоугольнике:

— (void) drawRectAtBottomOfScreen{

/* Получаем описатель текущего контекста. */

CGContextRef currentContext = UIGraphicsGetCurrentContext();

CGMutablePathRef secondPath = CGPathCreateMutable();

CGRect secondRect = CGRectMake(150.0f,

250.0f,

100.0f,

100.0f);

CGPathAddRect(secondPath,

NULL,

secondRect);

CGContextAddPath(currentContext,

secondPath);

[[UIColor purpleColor] setFill];

CGContextDrawPath(currentContext,

kCGPathFill);

CGPathRelease(secondPath);

}

— (void)drawRect:(CGRect)rect{

[self drawRectAtTopOfScreen];

[self drawRectAtBottomOfScreen];

}

Метод drawRect: сначала вызывает метод drawRectAtTopOfScreen, а сразу же после этого — метод drawRectAtBottomOfScreen. Мы не запрашивали создание тени для прямоугольника drawRectAtBottomOfScreen, но после запуска кода вы увидите примерно такой результат, как на рис. 17.25.

Рис. 17.25. Мы не собирались применять тень ко второму прямоугольнику, но она есть

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

В широком смысле прием сохранения и последующего восстановления графического контекста работает не только с тенями. В ходе такой операции восстанавливаются все данные, связанные с графическим контекстом (цвет заливки, шрифт, толщина линий и т. д.), — они возвращаются к установленным ранее значениям. Так, например, если до восстановления графического контекста вы работали с иными цветами заливки и обводки, чем те, что заданы в нем, то эти цвета будут сброшены.

Можно сохранять состояние графического контекста с помощью процедуры CGContextSaveGState и восстанавливать его прежнее состояние, используя процедуру CGContextRestoreGState. Так, если мы изменим процедуру drawRectAtTopOfScreen, сохранив состояние графического контекста до применения тени, а потом восстановим это состояние после того, как отрисуем путь, то результаты у нас получатся иные (рис. 17.26):

— (void) drawRectAtTopOfScreen{

/* Получаем описатель текущего контекста. */

CGContextRef currentContext = UIGraphicsGetCurrentContext();

CGContextSaveGState(currentContext);

CGContextSetShadowWithColor(currentContext,

CGSizeMake(10.0f, 10.0f),

20.0f,

[[UIColor grayColor] CGColor]);

/* Сначала создаем путь. Просто описатель пути. */

CGMutablePathRef path = CGPathCreateMutable();

/* Это границы прямоугольника. */

CGRect firstRect = CGRectMake(55.0f,

60.0f,

150.0f,

150.0f);

/* Добавляем прямоугольник к пути. */

CGPathAddRect(path,

NULL,

firstRect);

/* Добавляем путь к контексту. */

CGContextAddPath(currentContext,

path);

/* Задаем голубой в качестве цвета заливки. */

[[UIColor colorWithRed:0.20f

green:0.60f

blue:0.80f

alpha:1.0f] setFill];

/* Проводим путь в контексте и применяем к нему заливку. */

CGContextDrawPath(currentContext,

kCGPathFill);

/* Избавляемся от пути. */

CGPathRelease(path);

/* Восстанавливаем контекст в исходном состоянии

(в котором мы начали с ним работать). */

CGContextRestoreGState(currentContext);

}

Рис. 17.26. Сохранение состояния графического контекста для точного отображения теней

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



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

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

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

Обсуждение

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

Обсуждение Обычно после того, как пользователь успешно снимет фотографию на устройство с 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) на устройстве. Чтобы лучше понять, как работает этот механизм,


Обсуждение

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

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