OpenGL ES 【Opaque 屬性在 CAEAGLLayer 中的配置詳解】

UIView 的 alpha、hidden 和 opaque 屬性之間的關係和區別

UIView的這幾個屬性讓我困惑了好一陣子,通過翻看官方文檔stackoverflow等網上資源,對它們有了一定理解,現分享出來。如理解有誤,還請大家指出。

一、alpha
液晶顯示器是由一個個的像素點組成的,每個像素點都可以顯示一個由RGBA顏色空間組成的一種色值。其中的A就表示透明度alpha,UIView中alpha是一個浮點值,取值範圍0~1.0,表示從完全透明到完全不透明。
當把alpha的值設置成0以後:
1、當前的UIView和subview都會被隱藏,而不管subview的alpha值爲多少。
2、當前UIView會從響應者鏈中移除,而響應者鏈中的下一個會成爲第一響應者
alpha的默認值是1.0。
另外,更改alpha值時,默認是有動畫效果的,這是因爲圖層在Cocoa中是由Core Animation中CALayer表示的,該動畫效果是CALayer的隱含動畫。當然也有辦法禁用此動畫效果,在這就不多述了,感興趣的同學可以繼續關注後續的博客。

二、hidden
該屬性爲BOOL值,用來表示UIView是否隱藏,默認值是NO。
當值設爲YES時:
1、當前的UIView和subview都會被隱藏,而不管subview的hidden值爲多少。
2、當前UIView會從響應者鏈中移除,而響應者鏈中的下一個會成爲第一響應者
總之,同alpha爲0時的顯示效果相同。具體兩者之間有什麼區別就不清楚了,如果有知道的還望不吝賜教!

三、opaque
該屬性爲BOOL值,UIView的默認值是YES,但UIButton等子類的默認值都是NO。opaque表示當前UIView是否不透明,不過搞笑的是事實上它卻決定不了當前UIView是不是不透明,比如你將opaque設爲NO,該UIView照樣是可見的(上文說過,是否可見是由alpha或hidden屬性決定的),照理說爲NO就表示透明,那就應該是不可見的呀?
賣個關子,先看下圖:

前面講過,顯示器中的每個像素點都可以顯示一個由RGBA顏色空間組成的色值,比如上圖中有紅色和綠色兩個圖層色塊,對於沒有交叉的部分,即純紅色和綠色部分來說,對應位置的像素點只需要簡單的顯示紅或綠,對應的RGBA爲(1,0,0,1)和(0,1,0,1)就行了,負責圖形顯示的GPU需要很小的計算量就可以確定像素點對應的顯示內容。
問題是紅色和綠色還有相交的一塊,其相交的顏色爲黃色。這裏的黃色是怎麼來的呢?原來,GPU會通過圖層一和圖層二的顏色進行圖層混合,計算出混合部分的顏色,最理想情況的計算公式如下:Result = Source + Destination * (1 - SourceAlpha)

R = S + D * ( 1 – Sa )

其中,R表示混合結果的顏色,S是源顏色(位於上層的紅色圖層一),D是目標顏色(位於下層的綠色圖層二),Sa是源顏色的alpha值,即透明度。公式中所有的S和D顏色都假定已經預先乘以了他們的透明度。

知道圖層混合的基本原理以後,再回到正題說說opaque屬性的作用。當UIView的opaque屬性被設爲YES以後,按照上面的公式,也就是Sa的值爲1,這個時候公式就變成了:

R = S

即不管D爲什麼,結果都一樣。因此GPU將不會做任何的計算合成,不需要考慮它下方的任何東西(因爲都被它遮擋住了),而是簡單從這個層拷貝。這節省了GPU相當大的工作量。由此看來,opaque屬性的真實用處是給繪圖系統提供一個性能優化開關!

按照前面的邏輯,當opaque屬性被設爲YES時,GPU就不會再利用圖層顏色合成公式去合成真正的色值。因此,如果opaque被設置成YES,而對應UIView的alpha屬性不爲1.0的時候,就會有不可預料的情況發生,這一點蘋果在官方文檔中有明確的說明:
An opaque view is expected to fill its bounds with entirely opaque content—that is, the content should have an alpha value of 1.0. If the view is opaque and either does not fill its bounds or contains wholly or partially transparent content,the results are unpredictable. You should always set the value of this property to NO if the view is fully or partially transparent.
大家切記!!!!

四、最後
當把UIView的alpha屬性設成0,或者把hidden設成YES的時候,當前UIView和它所包含的子UIView都會變成不可見,同時也不會再響應event事件。注意這裏是或的關係,即只要設置了其中的一個都會有此效果,而不管另外一個屬性的值是什麼。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章