佈局的兩種模式
1,基於父視圖參考系的偏移frame 基於父視圖比例自動補償調整。
2,基於容器約束和內容壓力求解視圖位置 動態求解替代補償模式
內容壓力:負壓力(吸引邊框)正壓力(排斥邊框)
*經過alloc init出來的對象默認支持frame方法
*經過storyboard拖出來的默認支持auto layauto(約束)
平衡約束和內容壓力的優先級
約束自身的寬和高,,約定寬高比
容器、父視圖-----距離父視圖的上下左右各是多少,距離中心
同級視圖 寬高的關係,對齊
代碼建立約束 建立約束寬度
view!.attr1<relation>multi;tier * view2.attr2 + c.
NSLayoutConstraint * c1 = [NSLayoutConstraint constraintWithItem: attribute:(NSLayoutAttribute) relatedBy: toItem: attribute: multiplier: constant: ];
1.strut模式
strut的中文直譯有支持的意思,其佈局也取自此意。用通俗的翻譯來說這個機制就是:對父視圖的固定偏移。在學習UIView對象以後,咱們知 道,UIView對象能夠有自身的子視圖,同時負責維護子視圖的位置。而UIView自身的位置,則是經過CGRect類型的結構體變量frame所描 述,描述內容之中便包含基於父視圖的固定偏移量。
肯定位置,首先須要肯定參考系(也稱座標系)。只有在肯定參考系以後,才能根據參考系肯定自身的位置。在肯定參考系時有兩種狀況:
UIWindow對象的參考系
非UIWindow的視圖對象的參考系
首先咱們來研究UIWindow對象的參考系,因UIWindow對象顯示不須要父視圖,因此規定其位置的參考系即是屏幕自己。
參考系的規定以下
左上角頂點爲參考系原點
水平向右爲x正方向
垂直向下爲y正方向
參考系大小以下圖所示,不一樣機型的參考系不同
參考系大小於屏幕像素點關係
因爲歷史和當前市場產品的一些緣由,如今所描述的視圖參考系的大小並不等於手機屏幕真實的像素數量。以iPhone4爲例,其屏幕像素點的個數爲 高:960,寬:640。但描述屏幕的參考系大小爲480×320。經過簡單運算可知,屏幕像素爲參考系的2倍,即一個參考系中的點,須要用4個像素去描 繪,全部iPhone的顯示效果很是細膩。採用2倍大小的還有iPhone4s、iPhone五、iPhone5s、iPhone6
iPhone6 Plus的參考系和屏幕像素的關係較爲特殊。6Plus的參考系大小如圖所示爲x:414,y:736。同時6Plus的顯示芯片採用9個像素描繪一個點,使顯示內容更加細膩。這樣其顯示芯片須要生成一個2208×1242的圖像,爲參考系大小的3倍。
但6Plus爲兼容市面上絕大多數的大屏手機分辨率,本身的屏幕分辨率也設計爲1920×1080。爲了將顯示芯片渲染的2208×1242圖像顯 示在1920×1080的屏幕上,在顯示中,手機自動將原始圖像縮小1.15倍(2208÷1.15=1920)。因此,面向6Plus進行開發工做時, 開發人員和設計人員眼中的6Plus分辨率應該爲2208×1242,但用戶看到的實際大小應該爲1920×1080。
strut模式中,經過CGRect結構體變量描述一個基於參考系的矩形區域。其中包含該矩形區域左上角頂點在參考系中的位置和矩形自身的長和高。建立UIWindow對象時,經過UIScreen對象獲取當前屏幕的高度和寬帶用來建立UIWindow對象。
UIScreen * screen = [UIScreen mainScreen]; CGSize size = screen.bounds.size; CGPoint orgion = CGPointMake(0, 0); CGRect frame; frame.origin = orgion; frame.size = size; UIWindow * window = [[UIWindow alloc]initWithFrame:frame]; [window makeKeyAndVisible]; 肯定UIWindow位置和大小的參考系就是屏幕參考系。也能夠說,window對象的位置是基於屏幕。 接下來咱們繼續研究非UIWindow的視圖對象的參考系。因非UIWindow的視圖對象須要加入視圖樹中才可以被顯示,也就是須要做爲已經顯示在屏幕上的視圖的子視圖。 可以在屏幕上看到的視圖對象必定有一個父視圖,這個父視圖對象即是子視圖的參考系。默認狀況下,參考系的原點爲父視圖的左上角頂點,參考系的邊界爲父視圖的邊界。但此默認狀況能夠經過配置bounds屬性調整。 UIView * redView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 100, 100)]; 表示建立了一個視圖,這個視圖的左上角頂點,距離父視圖左上角頂點偏移了(50,50),自身的大小爲100×100。此時沒法肯定該視圖在屏幕上的位置,因還不知道父視圖在屏幕上的位置。全部這裏的frame屬性僅僅是基於父視圖的偏移量。 若是子視圖自身大小超出了父視圖的邊界,也就是參考系邊界,那麼超出部分是否顯示由父視圖決定,經過父視圖的clipsToBounds屬性 // When YES, content and subviews are clipped to the bounds of the view. //Default is NO. @property(nonatomic) BOOL clipsToBounds; bounds屬性 上文中說,視圖參考系默認狀況下是父視圖提供的,其原點爲父視圖的左上角頂點,參考系邊界爲父視圖邊界。但也能夠經過配置bounds屬性的值來調整參考系原點和邊界大小。 // default bounds is zero origin, frame size. @property(nonatomic) CGRect bounds; 在配置視圖的frame屬性時,bounds屬性也會自動變換,經過註釋能夠看出,其origin值爲zero,size值爲frame中的size值。 bounds的origin主要是改變子視圖參考系原點的位置。默認狀況下origin爲(0,0)表示:父視圖左上角頂點是子視圖參考系的原點。 但若是經過代碼改變其值爲(10,10),那麼父視圖左上角頂點將再也不是子視圖參考系的原點,而是(10,10)點,原點向上移動10個點,向左移動10 個點。這是,子視圖的frame沒有變換,可是父視圖參考系發送變換,一樣會引發子視圖的位置改變。這個屬性的使用場景這裏暫不展開講解。在以後章節中, 會進行深刻介紹。 一樣,咱們能夠經過bounds的size值來改變提供子視圖參考系的邊界大小。一般開發中不會主動調整此值,以避免帶來未知問題,例如按鈕不能點擊等,由於參考系邊界不只和現實相關還與時間傳遞有關,這裏暫不深刻。 2.spring模式 spring模式是位置的一種補償模式。經過上文中的strut模式能夠肯定一個子視圖在父視圖中的固定偏移量。可是再實際使用時,經常會出現父視 圖大小會發生改變的狀況。好比App有豎屏模式轉爲橫屏模式,此時若是不從新調整子視圖相對於父視圖的偏移量,將會出現現實錯誤。例以下圖: 這是便須要根據父視圖參考系的變化狀況,提供一個動態的補償機制,spring即是提供補償機制的模式。 補償機制是雙休的,因此須要父視圖的參考系發生變化時告知子視圖,同時子視圖須要根據變化作出相應的響應。 父視圖經過autoresizesSubviews屬性值來判斷,是否告知子視圖,自己的參考系發生變化。 // default is YES. //if set, subviews are adjusted according to their autoresizingMask if self.bounds changes @property(nonatomic) BOOL autoresizesSubviews 子視圖經過autoresizingMask屬性值作出相應的響應。 // simple resize. default is UIViewAutoresizingNone @property(nonatomic) UIViewAutoresizing autoresizingMask; UIViewAutoresizing爲響應狀況枚舉: UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5 autoresizingMask的默認值爲UIViewAutoresizingNone,表示子視圖的位置和大小按照當前在父視圖參考系中的比例進行調整。調整方式以下圖所示: 若是將autoresizingMask的值設置爲枚舉值中內容,那麼該內容表示的尺寸將不作調整,例如UIViewAutoresizingFlexibleWidth表示,子視圖自己的寬帶將不會隨父視圖參考系變化二變化,如圖所示 spring模式下的調整隻能進行按比例縮放和固定,沒法根據具體的要求進行補償,如今基本再也不使用此模式。 3.Auto Layout AutoLayout模式是iOS6 SDK所支持的新機制。使用AutoLayout能夠在不久層次結構中表示一個視圖與自身、父視圖、兄弟視圖的關係。這些關係能夠包含等式關係和不等式關 系,也可能涉及視圖的屬性,例如位置、範圍。這些特性使AutoLayout可以以一種spring模型沒法實現的方式實現精妙的邊界條件。舉例來講,你 可能會說「我想讓這些等尺寸的視圖排成一行,可是和父視圖的邊界距離不得小於20個點」或者「若是水平空間不足,我想在任何右邊按鈕受到影響前,讓左邊按 鈕的文本先被裁減」。 代碼中默認使用strut和spring模式。但從對spring和AutoLayout的功能描述上來看,兩個功能明顯衝突,都是對視圖的佈局進 行調整,spring是根據固定模式進行調整,而AutoLayout是須要根據約束進行求解。全部在同一個視圖對象上,只能使用兩種模式中的一共。須要 手動關閉strut和spring模式,才能使用AutoLayout模式。 關閉strut和spring的方法是經過視圖對象的一個方法,經過設置flag爲NO值,關閉strut和spring佈局模式。 - (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag 在AutoLayout模式下,每一個視圖對象在屏幕上的位置都是經過約束和內容壓力求解出來的。 3.1約束 約束就是視圖幾何關係的限制條件,主要能夠分紅三類: 自身約束:寬度約束、高度約束 相對父視圖約束:視圖四邊與父視圖四邊的距離、視圖水平中心與父視圖水平中心的距離、視圖垂直中心與父視圖垂直中心的距離。 兄弟視圖間約束:水平間距,垂直間距,邊緣對其,中心對其,尺寸匹配 兄弟視圖定義:擁有相同父視圖的視圖對象。 建立約束的方法有三種: 使用生成約束的方法建立約束 使用約束描述字符串生成約束 使用Interface Builder添加約束 首先咱們研究經過方法建立約束 UIView * view1; UIView * view2; NSLayoutAttribute att1; NSLayoutAttribute att2; CGFloat multiplier; CGFloat constant; NSLayoutRelation relation; NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:view1 attribute:att1 relatedBy:relation toItem:view2 attribute:att2 multiplier:multiplier constant:constant]; NSLayoutAttribute爲屬性枚舉參數: NSLayoutAttributeLeft = 1, NSLayoutAttributeRight, NSLayoutAttributeTop, NSLayoutAttributeBottom, NSLayoutAttributeLeading, NSLayoutAttributeTrailing, NSLayoutAttributeWidth, NSLayoutAttributeHeight, NSLayoutAttributeCenterX, NSLayoutAttributeCenterY, NSLayoutAttributeBaseline, Left,Right,Top,Bottom爲視圖的四個邊框 Leading,Trailing爲視圖的前邊和後邊。此處前邊和後邊是針對閱讀順序而言,對用中文,英文類的語言,左邊就是前邊,右邊就是後邊, 而對用阿拉伯文等從右向左閱讀的文字,前邊就是右邊,後邊就是左邊。一般建議使用先後作約束,避免使用左右,這樣能夠更好的進行國際化的適配。 Width,Height表示視圖自身的寬高屬性 CenterX,CenterY依次表示視圖自身水平中心和垂直方向的中心 Baseline爲顯示文字類組件特有的屬性,表示文字顯示的基線 NSLayoutRelation爲關係枚舉參數 NSLayoutRelationLessThanOrEqual = -1, NSLayoutRelationEqual = 0, NSLayoutRelationGreaterThanOrEqual = 1, 分別能夠設置等於,小於等於,大於等於。這裏在求解約束時,不等式較難理解。一般換一個角度去理解這個不等式,好比小於等於意思就是設置最大值,大於等於的意思就是設置最小值。 這段代碼演示了建立約束的通用方式,其約束規定的內容爲view1.attr1 關係 view2.attr2 * multiplier + constant。 下面咱們依次舉3個列子來說解如何建立約束: 建立一個viewA寬度爲10個點的約束 建立一個viewA的左邊界距離父視圖左邊界20個點的約束 建立一個viewA的右邊界距離viewB的右邊界30個點的約束 UIView * fatherView = [[UIView alloc]initWithFrame:CGRectZero]; fatherView.translatesAutoresizingMaskIntoConstraints = NO; UIView * viewA = [[UIView alloc]initWithFrame:CGRectZero]; viewA.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewA]; UIView * viewB = [[UIView alloc]initWithFrame:CGRectZero]; viewB.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewB]; //建立一個viewA寬度爲10個點的約束 NSLayoutConstraint * constraint_viewA_width = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:10]; //裝載約束到父視圖上 [fatherView addConstraint:constraint_viewA_width]; 建立一個viewA的左邊界距離父視圖左邊界20個點的約束 NSLayoutConstraint * constraint_superView_20_viewA = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:fatherView attribute:NSLayoutAttributeLeading multiplier:0 constant:20]; //裝載約束到父視圖上 [fatherView addConstraint:constraint_superView_20_viewA]; //建立一個viewA的右邊界距離viewB的右邊界30個點的約束 NSLayoutConstraint * constraint_viewA_30_viewB = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:viewB attribute:NSLayoutAttributeLeading multiplier:0 constant:30]; //裝載約束到父視圖上 [fatherView addConstraint:constraint_viewA_30_viewB]; >代碼中用NSLayoutAttributeLeading表示左邊,NSLayoutAttributeTrailing表示右邊 >視圖對象的約束必定要裝載到其父視圖身上,視圖對象的自我約束力不夠,須要父視圖管理才能夠。 接下來咱們繼續研究經過約束描述字符串生成約束用字符串主要描述一下兩點 * 邊界之間的間距 * 自己寬高 設計一下3個關鍵符號 * `| `表示父視圖邊界,根據字符串語義斷定哪一個邊界 * `[] `表示視圖對象,例如`[aView] `表示aView視圖對象,經過一個`@{@"aView":aView} `字典進行綁定 * `-x- `表示距離,x爲數組或字符,例如`-20- `或者`-tempX- `,經過一個`@{@"tempX":@20} `字典對字符串中的tempX進行數值綁定。 * `H: `表示水平方向 * `V: `表示垂直方向 舉例: * `H:[aView(100)] `表示aView的寬帶爲100 * `H:|-20-[aView] `表示aView的左邊界距離父視圖的左邊界爲20個點。 * `V:[aView]-10-| `表示aView的下邊界距離父視圖的下邊界爲10個點。 * `V:[aView(30)] `表示aView的高度爲30 採用字符串描述約束的核心優點是能夠同時描述多個視圖對象 * `H:|-20-[aView]-40-[bView(==aView)]-20-| `表示,aView和bView等寬,其間距40,分別距離父視圖兩邊20。 * `V:|-20-[aView(40)][bView(50)] `表示,aView高度40,距離父視圖上邊界20,bView高度50緊貼aView下邊。 經過NSLayoutConstraint的constraintsWithVisualFormat方法將描述約束的字符串生成約束對象。 NSString * constraint_string = @"|-x-[viewA(20)]"; NSDictionary merticsDic = @{@"x":@10}; NSDictionary viewsDic = @{@"viewA":viewA}; NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraint_string options:NSLayoutFormatDirectionLeadingToTrailing metrics:merticsDic views:viewsDic]; [fatherView addConstraints:constraints]; >方法中options參數是枚舉值,主要描述文字的閱讀方式是從左到右,仍是從右到左,一般選擇NSLayoutFormatDirectionLeadingToTrailing表示根據語言環境決定從前到後。 > NSLayoutFormatDirectionLeadingToTrailing, NSLayoutFormatDirectionLeftToRight, NSLayoutFormatDirectionRightToLeft, >方法中的metrics是一個字典,字典中的key爲字符串中描述數值的字符,value爲該字符對應的真實值。 >方法中的views是一個字典,字典中的key爲字符串中描述視圖對象的字符,value爲該字符對應的真實對象。爲了方便建立此類型字典UIKit中提供一個宏方便建立字典`NSDictionaryOfVariableBindings(<#...#>) `。 > NSDictionary * dic = NSDictionaryOfVariableBindings(aView); 至關於@{@"aView":aView}字典 >因一個字符串中能夠描述多個約束,因此返回一個數組,數組中爲此字符串描述的全部約束對象。 >經過調用父視圖的addConstraints方法,一次裝載多個約束。 下面咱們重複上節的3個列子來演示如何用描述字符串建立約束 * 建立一個viewA寬度爲10個點的約束 * 建立一個viewA的左邊界距離父視圖左邊界20個點的約束 * 建立一個viewA的右邊界距離viewB的右邊界30個點的約束 UIView * fatherView = [[UIView alloc]initWithFrame:CGRectZero]; fatherView.translatesAutoresizingMaskIntoConstraints = NO; UIView * viewA = [[UIView alloc]initWithFrame:CGRectZero]; viewA.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewA]; UIView * viewB = [[UIView alloc]initWithFrame:CGRectZero]; viewB.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewB]; //建立綁定字典 NSDictionary * views = NSDictionaryOfVariableBindings(fatherView,viewA,viewB); //建立一個viewA寬度爲10個點的約束描述字符串 NSString * constraintString1 = @"H:[viewA(10)]"; //經過字符串生成約束 NSArray * constraints1 = [NSLayoutConstraint constraintsWithVisualFormat:constraintString1 options:0 metrics:nil views:views]; //裝載約束到父視圖上 [fatherView addConstraints:constraints1]; //建立一個viewA的左邊界距離父視圖左邊界20個點的約束 NSString * constraintString2 = @"H:|-20-[viewA]"; //經過字符串生成約束 NSArray * constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:constraintString2 options:0 metrics:nil views:views]; //裝載約束到父視圖上 [fatherView addConstraints:constraints2]; //建立一個viewA的右邊界距離viewB的右邊界30個點的約束 NSString * constraintString3 = @"H:[viewA]-30-|"; //經過字符串生成約束 NSArray * constraints3 = [NSLayoutConstraint constraintsWithVisualFormat:constraintString3 options:0 metrics:nil views:views]; //裝載約束到父視圖上 [fatherView addConstraints:constraints3]; >經過對比能夠看出,經過描述字符串生成約束的方法更加簡單直觀。固然,更簡單的方式是經過IB(Interface Builder)添加約束,關於IB的使用,請參加視頻教程。 **3.2內容壓力** --- 內容壓力能夠影響裝載內容的對象外形尺寸。這裏用UIImageView對象舉例子,其餘裝載內容的視圖對象用法一致。 在AutoLayout模式下,內容能夠對組件邊界產生兩種壓力 * 正壓力:迫使組件改變自身的大小來顯示完整的內容。 * 負壓力:迫使組件維持當前的大小來顯示完整內容。 這樣描述比較抽象,舉個例子: 如今有一張200×200的圖片須要用一個UIImageView視圖對象來顯示。 **正壓力** 若是我這是UIImageView視圖對象的寬高都爲100,那麼內容會產生正壓力,迫使視圖的寬高都變爲200,這樣才能完整顯示圖片內容。 **負壓力** 若是我這是UIImageView視圖對象的寬高都爲300,那麼內容會產生負壓力(吸引力),迫使視圖的寬高都變爲200,這樣才能完整顯示圖片內容,而不留空白。 內容產生的壓力可否是視圖尺寸發送改變取決於如下兩個因素: * 壓力的大小 * 約束力的大小 >這裏的大小在代碼中用優先級來描述,優先級高的表明力量大,在求解時起主導做用。每個約束均可以配置其優先級,同時也能夠配置內容壓力的優先級。 壓力的優先級經過兩個方法分別進行配置 //設置正壓力的大小 [viewA setContentCompressionResistancePriority:<#(UILayoutPriority)#> forAxis:<#(UILayoutConstraintAxis)#>] //設置負壓力的大小 [viewA setContentHuggingPriority:<#(UILayoutPriority)#> forAxis:<#(UILayoutConstraintAxis)#>] >設置壓力時,須要經過Axis方法參數制定水平仍是數值方向,UILayoutConstraintAxis是枚舉類型,其枚舉值爲UILayoutConstraintAxisHorizontal和UILayoutConstraintAxisVertical。 >壓力優先級爲CGFloat類型,範圍是1-1000。其中系統給定了幾個默認值: > UILayoutPriorityRequired=1000 UILayoutPriorityDefaultHigh=750 UILayoutPriorityDefaultLow=250 UILayoutPriorityFittingSizeLevel=50 約束力的優先級經過約束的`priority `配置,在約束裝載到視圖以前能夠任意更改優先級,一旦,約束裝載到了視圖上,約束的優先級便不可再更改,若是須要更該,須要刪除以前的約束,從新建立。 @property UILayoutPriority priority; 其類型與壓力優先級一致。 下面咱們經過代碼演示一下內容壓力和約束力直接的較量。仍是經過本節一開始的例子,一個圖片大小爲200×200。一個UIImageView的寬高約束爲100×100。此時,UIImageView對象的最終大小由內容壓力和約束較量以後決定。 若是內容壓力大於約束力,最終UIImageView的大小爲200×200 //獲取一個圖片對象,該圖片大小爲200×200 UIImage * image = [UIImage imageNamed:@"testImage.jpg"]; //建立一個UIImageView顯示該圖片 UIImageView * imageView = [[UIImageView alloc]initWithImage:image]; imageView.translatesAutoresizingMaskIntoConstraints = NO; //設置其內容在水平和垂直方向的壓力爲501 [imageView setContentCompressionResistancePriority:501 forAxis:UILayoutConstraintAxisHorizontal]; [imageView setContentCompressionResistancePriority:501 forAxis:UILayoutConstraintAxisVertical]; //將視圖對象貼在視圖控制器的根視圖上 [self.view addSubview:imageView]; //建立距離父視圖左邊間接約束 NSArray * c1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c1]; //建立距離父視圖上邊間接約束 NSArray * c2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c2]; //建立視圖寬帶和高度的約束,並設置其約束力爲500小於501 NSLayoutConstraint * c3 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c3.priority = 500; [self.view addConstraint:c3]; NSLayoutConstraint * c4 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c4.priority = 500; [self.view addConstraint:c4]; 運行效果以下圖所示  若是內容壓力小於約束力 self.view.backgroundColor = [UIColor whiteColor]; //獲取一個圖片對象,該圖片大小爲200*200 UIImage * image = [UIImage imageNamed:@"testImage.jpg"]; //建立一個UIImageView顯示該圖片 UIImageView * imageView = [[UIImageView alloc]initWithImage:image]; imageView.translatesAutoresizingMaskIntoConstraints = NO; //設置其內容在水平和垂直方向的壓力爲501 [imageView setContentCompressionResistancePriority:499 forAxis:UILayoutConstraintAxisHorizontal]; [imageView setContentCompressionResistancePriority:499 forAxis:UILayoutConstraintAxisVertical]; [self.view addSubview:imageView]; //建立距離父視圖左邊間接約束 NSArray * c1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c1]; //建立距離父視圖上邊間接約束 NSArray * c2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c2]; //建立視圖寬帶和高度的約束,並設置其約束力爲500小於501 NSLayoutConstraint * c3 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c3.priority = 500; [self.view addConstraint:c3]; NSLayoutConstraint * c4 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c4.priority = 500; [self.view addConstraint:c4]; ``` 運行效果以下圖所示 內容驅動佈局是AutoLayout的核心優點,經過這樣的機制,能夠不寫代碼,便實現不一樣內容的顯示模式下,自動平衡視圖組件的尺寸。