Swift - constraint

約束

1.Storyboard中通過拖拽設(shè)置constraint;
2.VFL和原聲語法代碼設(shè)置constraint;
3.約束的常用優(yōu)雅的第三方框架:Objective - c - Masonry ,Swift - SnapKit

iOS布局機(jī)制 auto layout

  • 某個View(視圖)需要使用auto layout布局篓像,需要設(shè)置:
translatesAutoresizingMaskIntoConstraints = false
  • 幾個常用API
    1.intrinsinContentSize (在約束條件下褪秀,返回固有尺寸的內(nèi)容)
//就UILable而言下面這個方法比intrinsinContentSize先調(diào)用姨蝴,且修改后的tmpRect就是修改前的contentSize
override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect{ 
           var tmpRect = super.textRectForBounds(bounds, limitedToNumberOfLines: numberOfLines)            
           print("textRectForBoundsA:\(tmpRect)") 
           tmpRect.size.width += 15 
           tmpRect.size.height += 15
           print("textRectForBoundsB:\(tmpRect)") 
       return tmpRect 
}
//實現(xiàn)這些效果腹忽,只是應(yīng)為我們知道現(xiàn)有內(nèi)容所需的尺寸,并且在其內(nèi)容下擴(kuò)展闻察,就造成了這個臨界效果
override func intrinsicContentSize() -> CGSize { 
           var contentSize = super.intrinsicContentSize() 
//這個方法就是通過約束來返回一個渲染時內(nèi)容需要的Size捆探,會多次回調(diào) 
//(所謂的內(nèi)容所需要的size,比如一個label約束寬度為了300斤吐,但是內(nèi)容達(dá)不到這個寬度搔涝,返回的值可能是小于300的size厨喂。
eg:(267.5,14.5)),這個方法在一個控件完全需要內(nèi)容撐大的時候非常有效
           print(contentSize) 
           contentSize.width += 20 
           contentSize.height += 20 
           print(contentSize) 
       return contentSize 
}

使用:可以通過重寫這個方法來獲取健全約束后的控件frame,也可以改變其值再返回庄呈,這個方法只適合存在固有內(nèi)容的控件重寫蜕煌。比如:UILable、UIButton和UIImage诬留,其他不適固有內(nèi)容的View統(tǒng)一返回(-1,-1)
總結(jié):system auto layout 通過健全的約束和固有內(nèi)容來獲取該控件需 要的渲染的frame斜纪,就是用這個方法來回調(diào)獲得的,然后我們通過改變返回值文兑,來達(dá)到我們的各種效果盒刚。這個返回值的改變臨界值就是約束和改變后值取小。這句話的理解就是绿贞,改變后的size(30因块,30),而有一個約束條件是width <= 25,那么最終效果size就是 (25,30)

2.preferredMaxLayoutWidth
就我目前的手法而言籍铁,這個方法暫時沒什么用涡上,這個方法可以用一個上限約束 "<=" 代替,這個方法在不需要通過約束計算size的時候有效拒名,但是你在某種情況下需要計算出高度那么就需要設(shè)置這個屬性了(比如在ios7下計算撐大的cell高度)
a.這種方式在iOS9下無效吩愧,iOS8下設(shè)置有效

class LayoutLabel: UILabel {
    override func layoutSubviews() {
        self.preferredMaxLayoutWidth = self.frame.size.width
        super.layoutSubviews()
    }
}

b.這種方式在iOS9下也無效,iOS8下設(shè)置有效

  override func layoutSubviews() {
          super.layoutSubviews()
          self.titleLabel.preferredMaxLayoutWidth = self.titleLabel.bounds.width
          super.layoutSubviews()
      }

總結(jié):在iOS9下暫時只能如下處理(這么處理的缺點就是橫屏的時候不能滿足)

override func awakeFromNib() {
        super.awakeFromNib()
        self.titleLabel.preferredMaxLayoutWidth = UIScreen.mainScreen().bounds.width - 20
    }

3.sizeThatFits:方法和sizeToFit方法

let tmpsize = testTextView.sizeThatFits(self.testTextView.bounds.size) 
self.testTextViewHeightConstraint.constant = tmpsize.height

使用:類似上面的方法可以實現(xiàn)那種contentSize和高度一致的效果增显,不產(chǎn)生滾動條耻警。對于tableview實現(xiàn)這個還沒嘗試過,只測試了textView
總結(jié):調(diào)用sizeThatFits:并不改變View的size甸怕,它只是根據(jù)已有的content和給定的size計算出最合適的view的size甘穿。
4.systemLayoutSizeFittingSize:方法
對于固有內(nèi)容的View在布局完成之前獲得frame可以用intrinsinContentSize,
對于非自有內(nèi)容在布局完成之前要獲得一個View的frame那就需要這個方法了。使用這個方法之前確保約束的完整性能足夠撐大外層的view梢杭,否則約束不完整温兼,根據(jù)傳入的參數(shù)UILayoutFittingCompressedSize對應(yīng)size.width = 0
,UILayoutFittingExpandedSize對應(yīng)size.width = 1000
eg:動態(tài)計算cell的高度常用這個方法武契,此方法不能計算包含UITextView的募判,這種情況的解決方案就是,還是上面的計算然后加上textView的高咒唆,textView用上面的sizeThatFits:來計算
這個方法有時候要和preferredMaxLayoutWidth搭載一起使用才有效果

self.testLabelB.text = "這包含的另外一層意思" 
self.testLabelB.preferredMaxLayoutWidth = 300 
let outViewFitSize = self.testUIViewA.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize) 
print("outViewFitSize:\(outViewFitSize)")

總結(jié):就我的理解為什么要在這里設(shè)置preferredMaxLayoutWidth才有效果的原因届垫,因為以前不需要設(shè)置這個是因為由外到內(nèi)的約束都是完整的,可以計算出preferredMaxLayoutWidth全释,但是現(xiàn)在的情況是計算外層的size装处,那么就無法使用外層約束來揣測內(nèi)層約束,從而無法得到preferredMaxLayoutWidth浸船,那么就需要顯示聲明了

5.壓縮阻力(Compression Resistance)和 內(nèi)容吸附(Content

eeee.png

值越大妄迁,越不容易被壓縮和吸附(拉伸),用過自動布局就知道這種場景吧寝蹈,,場景:2個view并排登淘,Width都是>=0 ,且2邊都leading 0 箫老,training 為 0 ,你想要拉伸或者壓縮那個view呢黔州,就取決于這個條件約束

參考資料

http://zhangbuhuai.com/2015/07/16/beginning-auto-layout-part-1
https://www.mgenware.com/blog/?p=491
http://objccn.io/issue-3-5/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耍鬓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子流妻,更是在濱河造成了極大的恐慌界斜,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件合冀,死亡現(xiàn)場離奇詭異,居然都是意外死亡项贺,警方通過查閱死者的電腦和手機(jī)君躺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來开缎,“玉大人棕叫,你說我怎么就攤上這事∞壬荆” “怎么了俺泣?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長完残。 經(jīng)常有香客問我伏钠,道長,這世上最難降的妖魔是什么谨设? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任熟掂,我火速辦了婚禮,結(jié)果婚禮上扎拣,老公的妹妹穿的比我還像新娘赴肚。我一直安慰自己,他們只是感情好二蓝,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布誉券。 她就那樣靜靜地躺著,像睡著了一般刊愚。 火紅的嫁衣襯著肌膚如雪踊跟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天鸥诽,我揣著相機(jī)與錄音琴锭,去河邊找鬼晰甚。 笑死,一個胖子當(dāng)著我的面吹牛决帖,可吹牛的內(nèi)容都是我干的厕九。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼地回,長吁一口氣:“原來是場噩夢啊……” “哼扁远!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起刻像,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤畅买,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后细睡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谷羞,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年溜徙,在試婚紗的時候發(fā)現(xiàn)自己被綠了湃缎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡蠢壹,死狀恐怖颈将,靈堂內(nèi)的尸體忽然破棺而出屠阻,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布色罚,位于F島的核電站妒牙,受9級特大地震影響戚篙,放射性物質(zhì)發(fā)生泄漏涯肩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一沟优、第九天 我趴在偏房一處隱蔽的房頂上張望父能。 院中可真熱鬧,春花似錦净神、人聲如沸何吝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爱榕。三九已至,卻和暖如春坡慌,著一層夾襖步出監(jiān)牢的瞬間黔酥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留跪者,地道東北人棵帽。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像渣玲,于是被迫代替她去往敵國和親逗概。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容