陰影是繪制在圖形對象下面并偏移的圖像,使得陰影模擬投射到圖形對象上的光源的效果,如圖7-1所示。 文本也可以被遮蔽。 陰影可以使圖像呈現(xiàn)三維或仿佛浮動。

7-1 陰影
陰影有三個特點:
- x偏移量,它指定了水平方向上陰影偏離圖像的距離。
- y偏移量,它指定了垂直方向上陰影偏離圖像的距離。
- 模糊值,指定圖像是否具有硬邊緣(如圖7-2左側所示)或漫反射邊(如圖右側所示)。
本章介紹陰影如何工作,以及如何使用Quartz 2D API創(chuàng)建它們。

7-2 一個陰影沒有模糊和另一個與軟邊緣
陰影如何工作
Quartz中的陰影是圖形狀態(tài)的一部分。 您調用函數(shù)CGContextSetShadow,傳遞圖形上下文,偏移值和模糊值。 設置陰影后,您繪制的任何對象都會使用黑色繪制的陰影,該陰影在設備RGB顏色空間中具有1/3 alpha值。 換句話說,使用設置為{0,0,0,1.0 / 3.0}的RGBA值繪制陰影。
您可以通過調用函數(shù)CGContextSetShadowWithColor,傳遞圖形上下文,偏移值,模糊值和CGColor對象來繪制彩色陰影。 要為顏色提供的值取決于要繪制的顏色空間。
如果在調用CGContextSetShadow或CGContextSetShadowWithColor之前保存圖形狀態(tài),則可以通過恢復圖形狀態(tài)來關閉陰影。 您還可以通過將陰影顏色設置為NULL來禁用陰影。
陰影繪圖約定因上下文而異
前面描述的偏移指定陰影所在的位置與投射陰影的圖像相關。 這些偏移由上下文解釋并用于計算陰影的位置:
- 正x偏移指示陰影是在圖形對象的右邊。
- 在Mac OS X中,正y偏移指示向上位移。 這與Quartz 2D的默認坐標系匹配。
- 在iOS中,如果您的應用程序使用Quartz 2D API創(chuàng)建PDF或位圖上下文,正y偏移量表示向上位移。
- 在iOS中,如果圖形上下文是由UIKit創(chuàng)建的,例如由UIView對象創(chuàng)建的圖形上下文或通過調用UIGraphicsBeginImageContextWithOptions函數(shù)創(chuàng)建的上下文,則正y偏移指示向下位移。 這與UIKit坐標系的繪圖約定相匹配。
- 陰影繪制約定不受當前轉換矩陣的影響。
繪畫與陰影
按照以下步驟繪制陰影:
- 保存圖形狀態(tài)。
- 調用函數(shù)CGContextSetShadow,傳遞適當?shù)闹怠?/li>
- 執(zhí)行要應用陰影的所有繪圖。
- 恢復圖形狀態(tài)。
按照以下步驟繪制彩色陰影:
- 保存圖形狀態(tài)。
- 創(chuàng)建一個CGColorSpace對象,以確保Quartz正確解釋陰影顏色值。
- 創(chuàng)建一個CGColor對象,指定要使用的陰影顏色。
- 調用函數(shù)CGContextSetShadowWithColor,傳遞適當?shù)闹怠?/li>
- 執(zhí)行要應用陰影的所有繪圖。
- 恢復圖形狀態(tài)。
圖7-3中的兩個矩形用陰影繪制 - 一個帶有彩色陰影。

7-3 一個彩色的陰影和一個灰色陰影
清單7-1中的函數(shù)顯示了如何設置陰影來繪制如圖7-3所示的矩形。 每個編號的代碼行的詳細說明顯示在列表之后。
// 設置陰影的函數(shù)
void MyDrawWithShadows (CGContextRef myContext, // 1
CGFloat wd, CGFloat ht);
{
CGSize myShadowOffset = CGSizeMake (-15, 20);// 2
CGFloat myColorValues[] = {1, 0, 0, .6};// 3
CGColorRef myColor;// 4
CGColorSpaceRef myColorSpace;// 5
CGContextSaveGState(myContext);// 6
CGContextSetShadow (myContext, myShadowOffset, 5); // 7
// Your drawing code here// 8
CGContextSetRGBFillColor (myContext, 0, 1, 0, 1);
CGContextFillRect (myContext, CGRectMake (wd/3 + 75, ht/2 , wd/4, ht/4));
myColorSpace = CGColorSpaceCreateDeviceRGB ();// 9
myColor = CGColorCreate (myColorSpace, myColorValues);// 10
CGContextSetShadowWithColor (myContext, myShadowOffset, 5, myColor);// 11
// Your drawing code here// 12
CGContextSetRGBFillColor (myContext, 0, 0, 1, 1);
CGContextFillRect (myContext, CGRectMake (wd/3-75,ht/2-100,wd/4,ht/4));
CGColorRelease (myColor);// 13
CGColorSpaceRelease (myColorSpace); // 14
CGContextRestoreGState(myContext);// 15
}
這里是代碼做了什么:
- 采用三個參數(shù) - 圖形上下文以及在構建矩形時要使用的寬度和高度。
- 聲明并創(chuàng)建一個包含陰影偏移值的CGSize對象。這些值指定了對象左側15個單位和對象上方20個單位的陰影偏移。
- 聲明一個顏色值數(shù)組。這個例子使用RGBA,但是這些值不會有任何意義,除非它們與一個顏色空間一起傳遞給Quartz,這是Quartz正確解釋值的必要條件。
- 聲明顏色引用的存儲。
- 聲明顏色空間引用的存儲。
- 保存當前圖形狀態(tài),以便稍后恢復。
- 設置陰影以具有先前聲明的偏移值和模糊值5,這表示軟陰影邊緣。陰影將顯示為灰色,具有RGBA值{0,0,0,1 / 3}。
- 接下來的兩行代碼繪制圖7-3右側的矩形。你用你自己的圖形代碼替換這些行。
- 創(chuàng)建設備RGB顏色空間。在創(chuàng)建CGColor對象時,需要提供一個顏色空間。
- 創(chuàng)建一個CGColor對象,為設備提供RGB顏色空間和以前聲明的RGBA值。此對象指定陰影顏色,在本例中為紅色,Alpha值為0.6。
- 設置一個顏色陰影,提供您剛剛創(chuàng)建的紅色。陰影使用先前創(chuàng)建的偏移量,模糊值為5,表示軟陰影邊緣。
- 接下來的兩行代碼繪制圖7-3左側的矩形。你用你自己的圖形代碼替換這些行。
- 釋放彩色對象,因為它不再需要。
- 釋放顏色空間對象,因為它不再需要。
- 在設置陰影之前,將圖形狀態(tài)恢復為之前的狀態(tài)。