Autolayout中Hugging和Compression使用注意

前言html

本文主要側重Autolayout使用過程當中,經過代碼和SB添加含有intrinsicSize屬性控件約束的一些細節。編程

來自個人博客,歡迎訪問:To Be Independent.app

 

Hugging和Compression 屬性

有不少關於這兩個概念的文章,好比stackoverflow上Cocoa Autolayout: content hugging vs content compression resistance priority。我以爲很形象的說明了設置了有什麼用,可是還欠缺何時使用,即和`intrinsicSize`的關係。先來看下文檔上的說明:動畫

- contentCompressionResistancePriorityForAxis:
//Returns the priority with which a view resists being made smaller than its intrinsic size.

- contentHuggingPriorityForAxis:
//Returns the priority with which a view resists being made larger than its intrinsic size.

 

這麼一看,就很明瞭:對於有 intrinsicSize 屬性的控件(如UILabel,UIButton等),若是當前的frame比顯示的content範圍大,那麼設置的Hugging屬性起做用,不然設置的Compression屬性起做用。對於相應的數值,越大代表優先級越高,意味着當前的屬性佔優。簡單的說,對於須要Hugging的情形,hugging屬性的值越大(優先級越高),那麼代表控件須要緊湊的顯示。
Hugging和Compression屬性值有默認值:ui

  1. 對於純代碼添加的控件,Hugging默認250.0f,Compression默認 750.0f
  2. 經過SB添加,Hugging默認251.0f,Compression默認750.0f

爲何會有不同的值?那麼先看一下 UILayoutPriority的取值:this

static const UILayoutPriority UILayoutPriorityRequired NS_AVAILABLE_IOS(6_0) = 1000; // A required constraint.  Do not exceed this.

static const UILayoutPriority UILayoutPriorityDefaultHigh NS_AVAILABLE_IOS(6_0) = 750; // This is the priority level with which a button resists compressing its content.

static const UILayoutPriority UILayoutPriorityDefaultLow NS_AVAILABLE_IOS(6_0) = 250; // This is the priority level at which a button hugs its contents horizontally.

static const UILayoutPriority UILayoutPriorityFittingSizeLevel NS_AVAILABLE_IOS(6_0) = 50;// When you send -[UIView systemLayoutSizeFittingSize:], the size fitting most closely to the target size (the argument) is computed.  UILayoutPriorityFittingSizeLevel is the priority level with which the view wants to conform to the target size in that computation.  It's quite low.  It is generally not appropriate to make a constraint at exactly this priority.  You want to be higher or lower.

 

因而可知,在設計的時候,iOS的開發人員考慮到相似UILabel的控件首要的是顯示全部的內容。spa

編程實現

經過一段代碼,加載一個button:設計

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.translatesAutoresizingMaskIntoConstraints = NO;
button.backgroundColor = [UIColor redColor];
[button setTitle:@"a long long title" forState:UIControlStateNormal];
[self.view addSubview:button];

NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0f constant:100.0f];
[self.view addConstraint:constraint];

constraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:100.0f];
[self.view addConstraint:constraint];

constraint = [[NSLayoutConstraint constraintWithItem:button1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:0 constant:50.0f];
[self.view addConstraint:constraint];

 

如上添加的constraint,使得button的frame不足以顯示標題內容,注意上述constraint默認的優先級都是UILayoutPriorityRequired。所以咱們能夠經過修改最後一個寬度的constraint:code

constraint.priority = UILayoutPriorityDefaultHigh - 1;

 

對於用SB添加的控件,也能夠用相似的方法修改。至於爲何,SB中添加的如UILable的控件,當給其添加某個約束後,SB中Hugging屬性的值是251呢?這是爲了默承認以顯示全內容。此時,你能夠在sb中手動把空間尺寸變小,再把控件的某個屬性的constriant(width或tailing)的優先級設置爲low。這時,你也能夠在SB中發現相應的約束由藍色實線變成了藍色虛線。固然,若是compression約束起做用的狀況下,約束也是藍色虛線。orm

與其它控件一塊兒使用

如上單個控件能夠正常使用,若是設置一個相鄰的控件,會有什麼須要注意的嗎?答案是NO,什麼都不須要操心,仍舊按以前的方法添加約束,這極大的簡化了工做量。
另外,這裏須要說明的是,須要更新控件上文字的時候,爲了有一個較好的動畫效果,須要:

[label.superView layoutIfNeeded];
相關文章
相關標籤/搜索