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. Сохранение состояния графического контекста для точного отображения теней
17.10. Отрисовка градиентов
Постановка задачи
Требуется рисовать в графическом контексте градиенты, используя различные цвета.
Решение
Воспользуйтесь функцией CGGradientCreateWithColor.
Обсуждение
Мы уже поговорили о цвете в разделе 17.3 и теперь попробуем воспользоваться нашими навыками для решения более интересных задач, чем рисование простых прямоугольников и разноцветного текста.