一周隨筆--15.11.08,隨筆--15.11.08
一周新知識點記錄(15.11.08)一、
關於
hidden
、
alpha
、
opaque
的說明
這3個都是UIView的屬性:
hidden:YES或者NO,YES時隱藏UIView對象,並且無法再響應手勢(從響應鏈中移除),其上的子視圖也被隱藏且無法響應手勢;
alpha:透明度(0~1.0) 0為完全透明,1為不透明。設定為0時,相當於hidden設定為YES,同樣無法響應手勢。其上的子視圖也將完全透明且無法響應手勢。
opaque:從名字來看,是否不透明。然而將其設定為NO,意思上看是設定成了透明,然而運行發現仍然是可見的。事實上,這個屬性並不是直接設定UIView對象是否透明,它其實用來最佳化效能的,是給繪圖系統提供一個效能最佳化開關。如果UIView對象完全不透明(即alpha為1),就將其設定成YES。如果UIView對象不完全不透明(alpha不為1),就將其設定成NO,若設定成YES可能會有不可預見的結果。
這樣做能夠大大提升UIView在繪製時的效能,節省GPU的消耗。具體見http://blog.csdn.net/martin_liang/article/details/40739845
二、Quartz2D補充整理
座標系
1、Quartz座標系統預設原點位於左下角,x正軸向右,y正軸向上。
2、在UIKit中的座標系統中,原點位於左上方;而Quartz的座標系統原點位於左下角。在UIView中獲得的圖形上下文(Graphics Context),系統已經將座標系統轉變成了UIKit的座標系,是通過將圖形內容相關的CTM原點平移到左上方,同時將y軸反轉(y值乘以-1)得到的。因此在繪製UIView時不需要再對擷取到得圖形上下文再作座標系的調整(已經匹配UIView的座標系了)。
3、對於位元影像(bitmap),通過UIGraphicsBeginImageContextWithOptions建立的位元影像圖形上下文(bitmap graphics context),其座標系統原點是在左上方的,和UIView的圖形上下文座標系統一樣,系統已經自動對其進行了轉換。
注意:
(1)只是通過UIGraphicsBeginImageContextWithOptions建立的位元影像圖形上下文座標系統是自動做了轉換的,如果通過CGBitmapContextCreate手動建立位元影像圖形上下文,其座標系統依舊是Quartz的座標系統,即以左下角為原點,y軸正方向從下到上。
(2)在drawRect的圖形上下文或者UIGraphicsBeginImageContextWithOptions擷取的圖形上下文中通過CGContextDrawImage方法繪製圖片,繪製結果發現圖片是倒置的。既然上面說圖形上下文已經轉換成了UIKit的座標系,原點在左上方,又怎麼會倒置呢?原因在於CGContextDrawImage方法傳入的參數CGImage的座標系是倒置的,避免這種情況可以通過對UIImage調用drawInRect繪製。
(3)必要的時候需要翻轉座標系,方法是 :
CGContextTranslateCTM(cox, 0, height);
CGContextScaleCTM(cox, 1.0, -1.0);
繪製漸層
可以通過CGShading對象或者CGGradient對象繪製漸層,CGGradient易於重用且用法簡單,這裡只介紹使用CGGradient繪製漸層。
主要步驟:
(1)建立一個CGGradient對象,提供一個色彩空間,一個包含兩個或更多顏色組件的數組,一個包含兩個或多個位置的數組,和漸層顏色個數。
(2)調用CGContextDrawLinearGradient(軸向)或CGContextDrawRadialGradient(徑向)函數並提供一個上下文、一個CGGradient對象、繪製選項和開始結束幾何圖形來繪製漸層。
(3)當不再需要時釋放CGGradient對象。
程式碼範例:
//建立漸層梯度對象方法一// size_t numOfLocations = 3; //位置數// CGFloat locations[3] = {0, 0.5, 1}; //元素取值0~1 表示位置點到軸線起點的距離與軸線長度的比例// CGFloat components[12] = {1.0, 0.5, 0.4, 1.0, 0.8, 0.8, 0.3, 1.0, 0.5,0.5,0.5,1.0}; //顏色組件 元素個數為4的倍數(RGBA*位置數)// CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, numOfLocations);
//建立漸層梯度對象方法二 CGFloat locations[3] = {0, 0.5, 1}; NSArray *colors = [NSArray arrayWithObjects: (id)[UIColor colorWithRed:0.540 green:1.000 blue:0.814 alpha:1.000].CGColor, (id)[UIColor colorWithRed:1.000 green:0.687 blue:0.695 alpha:1.000].CGColor, (id)[UIColor colorWithRed:0.970 green:1.000 blue:0.488 alpha:1.000].CGColor,nil]; CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(__bridge CFArrayRef)colors, locations); //繪製軸向漸層 CGContextDrawLinearGradient(cox, gradient, CGPointZero, CGPointMake(rect.size.width, rect.size.height), 0); //繪製放射狀漸層// CGContextDrawRadialGradient(cox, gradient, CGPointMake(50, 50), 25, CGPointMake(250, 500), 50, 0);
CGColorSpaceRelease(colorSpace); CGGradientRelease(gradient);
透明層
透明層是一個獨立於圖形內容相關的目標緩衝,當需要在一組對象上使用特效時,透明層非常有用,它會把一組對象看成是一個整體來進行特效的繪製。以繪製3個矩形的陰影為例:
未使用透明層:
CGSize myShadowOffset = CGSizeMake (10, -10); CGContextSetShadow (cox, myShadowOffset, 5);
CGContextSetRGBFillColor (cox, 0, 1, 0, 1); CGContextFillRect (cox, CGRectMake (20, 20,80,80)); CGContextSetRGBFillColor (cox, 0, 0, 1, 1); CGContextFillRect (cox, CGRectMake (80,80,80,80)); CGContextSetRGBFillColor (cox, 1, 0, 0, 1); CGContextFillRect (cox, CGRectMake (140,140,80,80));
使用透明層:
CGSize myShadowOffset = CGSizeMake (10, -10); CGContextSetShadow (cox, myShadowOffset, 5); CGContextBeginTransparencyLayer (cox, NULL); //開啟透明層 然後開始繪製 CGContextSetRGBFillColor (cox, 0, 1, 0, 1); CGContextFillRect (cox, CGRectMake (20, 20,80,80)); CGContextSetRGBFillColor (cox, 0, 0, 1, 1); CGContextFillRect (cox, CGRectMake (80,80,80,80)); CGContextSetRGBFillColor (cox, 1, 0, 0, 1); CGContextFillRect (cox, CGRectMake (140,140,80,80)); CGContextEndTransparencyLayer (cox); //關閉透明層
參考文檔:
[《Quartz 2D編程指南》](http://southpeak.github.io/blog/2014/11/10/quartz-2dbian-cheng-zhi-nan-zhi-%5B?%5D-:gai-lan/)
三、區分解析度、像素、點、尺寸
解析度、像素,通常用在螢幕或者圖片的說明上,用來表明清晰度。我們通常說這個螢幕的解析度是多少多少,網路攝影機像素多少多少,具體什麼意思呢?
以解析度為320*480的iphone3GS螢幕(一倍屏)為例說明:
像素:像素是組成圖象的最基本單元要素(最小單元),該螢幕長方向上有320個像素,寬方向上有480個像素。320*480約等於15萬,就說這個螢幕的像素為15萬。一個像素只能顯示一種顏色
解析度:解析度是指在長和寬的兩個方向上各擁有的像素個數,上面的320*480就是解析度的表現形式。
尺寸:尺寸則是螢幕的實際長寬,例如iphone4為3.5英寸,指的時螢幕對角線長度為3.5英寸,1英寸=25.4毫米。
點:點用來構建一個座標系,它是根據實際情況和需求制定的,是人為設想的,並不是真實存在的。在ios開發中,座標系的單位長度就是點。在iphone3GS上,一個點包含一個像素,這種螢幕俗稱一倍屏;iphone4、4s、iphone5等2倍retina屏上,一個點包含兩個像素(這裡說的是一維的長度,從二維的角度來講,一個點包含4個像素,長寬2*2嘛),也就是二倍屏,用@2x表示這種螢幕模式;對於3倍retina的iphone6p和iphone6sp,一個點包含3個像素。開發中在通過點搭建的座標系中布局介面,方便適配,因為無需再去理會螢幕的解析度,系統會在顯示的時候自動進行適配。
補充:
- 每個像素大小是不確定的,它由螢幕的尺寸和解析度決定。
- 通常所說的像素點就是像素,並不是上面所說的點。
- 同一張圖片或者解析度相同的圖片在不同的螢幕上顯示的大小是不一樣的,由螢幕像素大小決定。
A&B->C
C&D->E
A:螢幕解析度
B:螢幕尺寸
C:螢幕像素大小
D:圖片解析度
E:圖片在螢幕上的顯示尺寸
- 若圖片解析度和螢幕解析度相同,則剛好能完全顯示;圖片解析度<螢幕解析度,圖片不能完全顯示,若將其展開填充整個螢幕,圖片清晰度就會下降;圖片解析度>螢幕解析度,圖片顯示不下。
參考文章:
[《像素和解析度的關係》](http://www.360doc.com/content/13/0630/15/3398926_296570170.shtml)
[《iOS的APP如何適應iPhone5s/6/6Plus三種螢幕的尺寸》](http://my.oschina.net/u/1049180/blog/362599)
四、iphone
螢幕適配規則
有時候運行程式,發現介面上下出現了黑框,這是由於當前程式沒有適配iphone5的螢幕導致的。我們知道,iphone5螢幕像素640*1136,比iphone4的640*960在高度上多了176個像素,即88個點,假如程式沒有適配iphone5,那麼運行在iphone5上的結果就是上下各有高度為44個點的黑邊。
那麼系統是怎樣得知是否已經適配了iphone5的呢?如果你以為啟動圖片的作用僅僅是為了在進入app前顯示一張圖片,那你就錯了。它更大的職能其實是在圖片顯示期間做一些初始化處理,其中包括檢查適配情況。這通常比較費時,先出現啟動圖片,可以使使用者覺得系統立即有了響應,減少等待的焦慮感,套路簡直深!
對於iphone6而言,如果沒有適配iphone5,也沒有適配iphone6,那麼程式遠程時同樣上下留黑邊。如果適配了iphone5而沒有適配iphone6,這時候運行,程式能全螢幕顯示了,但是會發現清晰度不太對,因為iphone5和iphone螢幕長寬比例是一樣的,因此只是將iphone5的程式單純放大了,因此看上去會有點模糊。如果適配了iphone6,就不會存在這種問題了。iphone6s也是同樣的道理。而系統識別適配的方法同樣是根據是否設定了相應螢幕的啟動圖來判斷。
目前所有iphone機型共有5中螢幕(豎屏):
Retina1x(320*480)(iphone3GS之前,現已不用搭理)
Retina2x(640*960)(iphone4/4s)
Retina4(640*1136)(iphone5/5s/5c)
Retina HD4.7(750*1334)(iphone6/6s)
Retina HD5.5(1242*2208)(iphone6p/6sp)
參考:
[《iOS的APP如何適應iPhone5s/6/6Plus三種螢幕的尺寸》](http://my.oschina.net/u/1049180/blog/362599)
五、
啟動圖設定方法
一、使用LaunchImage
在工程Targets-App Icons and Launch Images-Launch Image Source中設定啟動圖資來源目錄,在Assets.xcassets中的啟動圖資源檔夾中設定相應螢幕的啟動圖。這種方法相容ios7,ios8。
二、使用LauchScreen.xib
這是Xcode6/iOS8的新功能,也就是說不支援iOS7。所以現在的做法還是使用LaunchImage,將來程式不再需要相容ios7之後或許LauchScreen.xib能得到廣泛應用。
注意:Xcode預設將LaunchScreen.xib作為啟動方式,如果不用LauchScreen.xib設定啟動圖,將工程Targets-App Icons and Launch Images-Launch Screen File設定為空白即可。
[《Launch Screen在iOS7/8中的實現》]http://blog.shiqichan.com/Launch-Screen-in-iOS-7-and-8/
六、
ios
中貝茲路徑
UIBezierPath是UIKit架構對於Quartz2D架構CGPathRef的封裝,通過它方便繪製,但是也要在繪製圖形上下文環境中。
UIBezierPath有一個CGPathRef類型的屬性CGPath,通過它與CG架構實現聯絡。
通常UIBezierPath的CGPath屬性用在為CAShapeLayer提供渲染的形狀。
七、 CAShapeLayer
1、CAShapeLayer是一種特殊的層,可以在上面渲染圖形。
2、CAShapeLayer繼承自CALayer,可使用CALayer的所有屬性。
3、CAShapeLayer需要和貝茲路徑配合使用才有意義,貝茲路徑為其提供渲染的圖形。
4、使用CAShapeLayer與貝茲路徑可以實現不再view的drawRect方法中畫出一些想要的圖形。
關於CAShapeLayer和drawRect的比較:
在drawRect中繪製圖形調用CoreGraphics架構中的方法,佔用CPU,消耗效能大;
CAShapeLayer屬於CoreAnimation架構,通過GPU來渲染圖形,節省效能。動畫渲染直接提交給GPU,不消耗記憶體。
用法見Demo http://download.csdn.net/detail/lotheve/9248547
八、
CAGradientLayer
1、CAGradientLayer是一種特殊的層,用於渲染漸層效果。
2、CAGradientLayer繼承自CALayer,可使用CALayer所有的屬性。
3、CAGradientLayer是除了在圖形上下文繪製漸層效果外的另一種方法,它不需要藉助圖形上下文,是直接渲染在層上的,因此便於使用。
使用見Demo http://download.csdn.net/detail/lotheve/9248547