在iOS開發(fā)中UIView有一些不常用的屬性及方法砸王。下面做一些簡單介紹:
1鄙陡、autoresizingMask
setAutoresizingMask控件的自適應(yīng)
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone? ? ? ? ? ? ? ? = 0,
UIViewAutoresizingFlexibleLeftMargin? = 1 << 0,
UIViewAutoresizingFlexibleWidth? ? ? ? = 1 << 1,
UIViewAutoresizingFlexibleRightMargin? = 1 << 2,
UIViewAutoresizingFlexibleTopMargin? ? = 1 << 3,
UIViewAutoresizingFlexibleHeight? ? ? = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
1乃正、UIViewAutoresizingNone? 這個屬性是指,控件相對于父視圖坐標沒有任何改變(不管父視圖的長寬改變?yōu)槎嗌偎鳎涌丶淖鴺耸嵌ㄖ担?br>
2他挎、UiViewAutoresizingFlexibleleftMargin ? ? ? ? 控件相對于父視圖,隨著父視圖的寬度比例變化捡需,橫坐標跟著變化办桨,比如說上面的lable frame = CGRectmake(50,100,200,40); ? 如果之前父視圖的長寬是320*480 ?現(xiàn)在變成了480*320 ?那么在父視圖改變之后,如果只限制這一個屬性站辉,那么變化后的lable橫坐標就變?yōu)椋?50*(480/320) lable的坐標就是:(50*(480/320)呢撞,100,200饰剥,40)殊霞;
3、UIViewAutoresizingFlexibleRightmargin 汰蓉、?UIViewAutoresizingFlexibleTopmargin 绷蹲、?UIViewAutoresizingFlexibleBottommargin ?三個屬性和2)類似;
4顾孽、UIViewAutoResizingFlexibleWidth ?和2類似祝钢,只不過是lable的寬度按照比例發(fā)生改變
2、UIView 的transform屬性
UIView的transform屬性若厚,通過設(shè)置該屬性拦英,我們可以實現(xiàn)調(diào)整該view在其superView中的大小和位置,具體來說,Transform(變化矩陣)是一種3×3的矩陣,通過這個矩陣我們可以對一個坐標系統(tǒng)進行縮放测秸,平移疤估,旋轉(zhuǎn)以及這兩者的任意組著操作。而且矩陣的操作不具備交換律霎冯,即矩陣的操作的順序不同會導(dǎo)致不同的結(jié)果铃拇。
獲得CGAffineTransform有多種方法,例如使用CGAffineTransformMake沈撞,但是對于矩陣操作相對比較麻煩锚贱,但是事實上iOS已經(jīng)為我們提供好了三個對應(yīng)的方法,分別用于在原來的角度关串、縮放拧廊、移動位置的基礎(chǔ)上做出修改:CGAffineTransformRotate、CGAffineTransformScale晋修、CGAffineTransformTranslate
view.transform=CGAffineTransformScale(view.transform, 0.5, 0.5);//? 實現(xiàn)的是放大和縮小
view.transform=CGAffineTransformRotate(view.transform, M_PI); //實現(xiàn)的是旋轉(zhuǎn)
view.transform=CGAffineTransformTranslate(view.transform,20, 20);//實現(xiàn)的是平移
創(chuàng)建一個CGAffineTransform transform對象
CGAffineTransform transform;
transform = CGAffineTransformRotate(manImageView.transform,M_PI/6.0);//設(shè)置旋轉(zhuǎn)度數(shù)
[UIView beginAnimations:@"rotate" context:nil ];//動畫開始
[UIView setAnimationDuration:2];//動畫時常
[UIView setAnimationDelegate:self];//添加代理
[manImageView setTransform:transform];//獲取transform的值
[UIView commitAnimations];//關(guān)閉動畫
3吧碾、UIView的contentMode屬性
這個屬性的值決定了,當視圖的幾何形狀變化時如何復(fù)用它的內(nèi)容墓卦。當視圖第一次展示前倦春,它會將自己的內(nèi)容渲染成一張底層的bitmap. 然后視圖的幾何變化都不會使bitmap重新生成。而視圖contentMode屬性的值決定了bitmap是否縮放落剪、位置在哪兒(固定在左邊睁本、右邊、上面忠怖、下面呢堰、居中)。默認情況下凡泣,contentMode的值是UIViewContentModeScaleToFill枉疼。
UIViewContentModeScaleToFill ? ? ? //改變內(nèi)容的高寬比例,縮放內(nèi)容鞋拟,UIView中完整顯示內(nèi)容骂维,填滿UIView
UIViewContentModeScaleAspectFit ? ? //保持內(nèi)容的高寬比,縮放內(nèi)容贺纲,完整顯示內(nèi)容航闺,最大化填充UIview,沒填充上的區(qū)域透明
UIViewContentModeScaleAspectFill ? ? ?//保持內(nèi)容高寬比猴誊,縮放內(nèi)容死相,超出視圖的部分內(nèi)容會被裁減,填充UIView
UIViewContentModeRedraw ? ? //當View的bounds改變德崭,系統(tǒng)會調(diào)用setNeedsDisplay荔睹,重新繪制視圖
UIViewContentModeCenter ? ? ? ? ? ? ? ?//不縮放,內(nèi)容在視圖中間
UIViewContentModeTop ? ? ? ? ? ? ? ? ?//內(nèi)容在視圖頂部
UIViewContentModeBottom ? ? ? ? ? //內(nèi)容在視圖底部
UIViewContentModeLeft ? ? ? ? ? ? ? ?//內(nèi)容在視圖左邊
UIViewContentModeRight ? ? ? ? ? //內(nèi)容在視圖右邊?
UIViewContentModeTopLeft ? ? ? ? ? //?the top-left corner of the view.
UIViewContentModeTopRight ? ? ? ? ? ?//?the top-right corner of the view.
UIViewContentModeBottomLeft ? ? ? //the bottom-left corner of the view.
UIViewContentModeBottomRight ? ? ? ? ? //?the bottom-right corner of the view.
4项阴、layoutSubviews方法
這個方法滑黔,默認沒有做任何事情,需要子類進行重寫 环揽。 系統(tǒng)在很多時候會去調(diào)用這個方法:
1略荡、初始化不會觸發(fā)layoutSubviews,但是如果設(shè)置了不為CGRectZero的frame的時候就會觸發(fā)歉胶。
2汛兜、addSubview會觸發(fā)layoutSubviews
3、設(shè)置view的Frame會觸發(fā)layoutSubviews通今,當然前提是frame的值設(shè)置前后發(fā)生了變化
4粥谬、滾動一個UIScrollView會觸發(fā)layoutSubviews
5肛根、旋轉(zhuǎn)Screen會觸發(fā)父UIView上的layoutSubviews事件
6、改變一個UIView大小的時候也會觸發(fā)父UIView上的layoutSubviews事件
在蘋果的官方文檔中強調(diào): You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want.layoutSubviews, 當我們在某個類的內(nèi)部調(diào)整子視圖位置時漏策,需要調(diào)用派哲。反過來的意思就是說:如果你想要在外部設(shè)置subviews的位置,就不要重寫掺喻。
5芭届、setNeedsLayout方法
標記為需要重新布局,不立即刷新感耙,但layoutSubviews一定會被調(diào)用
配合layoutIfNeeded立即更新
6褂乍、layoutIfNeeded方法
如果,有需要刷新的標記即硼,立即調(diào)用layoutSubviews進行布局
7逃片、drawRect方法
這個方法是用來重繪的。
drawRect在以下情況下會被調(diào)用:
1谦絮、如果在UIView初始化時沒有設(shè)置rect大小题诵,將直接導(dǎo)致drawRect不被自動調(diào)用。drawRect調(diào)用是在Controller->loadView, Controller->viewDidLoad 兩方法之后掉用的.所以不用擔(dān)心在控制器中,這些View的drawRect就開始畫了.這樣可以在控制器中設(shè)置一些值給View(如果這些View draw的時候需要用到某些變量值).
2层皱、該方法在調(diào)用sizeToFit后被調(diào)用性锭,所以可以先調(diào)用sizeToFit計算出size。然后系統(tǒng)自動調(diào)用drawRect:方法叫胖。
3草冈、通過設(shè)置contentMode屬性值為UIViewContentModeRedraw。那么將在每次設(shè)置或更改frame的時候自動調(diào)用drawRect:瓮增。
4怎棱、直接調(diào)用setNeedsDisplay,或者setNeedsDisplayInRect:觸發(fā)drawRect:绷跑,但是有個前提條件是rect不能為0拳恋。以上1,2推薦;而3,4不提倡
drawRect方法使用注意點:
1砸捏、若使用UIView繪圖谬运,只能在drawRect:方法中獲取相應(yīng)的contextRef并繪圖。如果在其他方法中獲取將獲取到一個invalidate的ref并且不能用于畫圖垦藏。drawRect:方法不能手動顯示調(diào)用梆暖,必須通過調(diào)用setNeedsDisplay 或者 setNeedsDisplayInRect,讓系統(tǒng)自動調(diào)該方法掂骏。
2轰驳、若使用calayer繪圖,只能在drawInContext: 中(類似于drawRect)繪制,或者在delegate中的相應(yīng)方法繪制级解。同樣也是調(diào)用setNeedDisplay等間接調(diào)用以上方法3冒黑、若要實時畫圖,不能使用gestureRecognizer蠕趁,只能使用touchbegan等方法來掉用setNeedsDisplay實時刷新屏幕
8薛闪、sizeToFit方法
sizeToFit會自動調(diào)用sizeThatFits方法;
sizeToFit不應(yīng)該在子類中被重寫俺陋,應(yīng)該重寫sizeThatFits
sizeThatFits傳入的參數(shù)是receiver當前的size,返回一個適合的size
sizeToFit可以被手動直接調(diào)用sizeToFit和sizeThatFits方法都沒有遞歸昙篙,對subviews也不負責(zé)腊状,只負責(zé)自己