從intrinsicContentSize到自動調整佈局self-sizing

PeachRain發表於2017-12-14

# 1. intrinsic Content Size

什麼是intrinsicContentSize?這個屬性是在哪裡的?

剛開始看到這個肯定會有很多的疑問。

本人接觸到這個也是因為功能的需要。(一個自動適應cell內容的collectionview)。

在剛程式設計的時候,第一想到的還是手動適應,計算contentSize然後設定frame適應內容,但是這樣給人的感覺還是有點low啊.

果斷換其他方法。直到發現了intrinsicContentSize這個便捷的屬性,簡直不要太興奮。

那到底什麼是intrinsicContentSize呢?

Intrinsic Contenet Size – Intrinsic Content Size:固有的大小。

在AutoLayout中,它作為UIView的屬性(不是語法上的屬性),意思就是說我知道自己的大小,如果你沒有為我指定大小,我就按照這個大小來。

比如:大家都知道在使用AutoLayout的時候,UILabel是不用指定尺寸大小的,只需指定位置即可,就是因為,只要確定了文字內容,字型等資訊,它自己就能計算出大小來。

同樣的UILabel,UIImageView,UIButton等這些元件及某些包含它們的系統元件都有 Intrinsic Content Size 屬性,也就說他們都有自己計算size的能力。

同樣的會發現UICollectionView也有這個屬性。

# 利用intrinsicContentSize自動計算size

>那如何利用intrinsicContentSize呢。

>既然intrinsicContentSize能夠自己計算,當然我們也可以手動指定他的大小,這樣會有

>人說。那不還是自己計算嗎?

>其實不是,當我們改變UICollectionView中cell的約束和內容時,UICollectionView是會自動計算size適應的,這就是contentSize,每當改變contentSize也會隨著改變,計算UICollectionView都幫我們算好了,我們就可以利用contentSize來設定內容的size.

>使用在UICollectionView中的 -(CGSize)intrinsicContentSize: 方法。

並且在需要改變這個值的時候呼叫:invalidateIntrinsicContentSize 方法,通知系統這個值改變了,如下

```

//重寫該方法返回一個size

override func intrinsicContentSize() -> CGSize {

//此處你可以返回一個自己設定的size值,當然也可以返回contentSize

return self.contentSize

}

```

>但是有人比較懶不想主動呼叫方法,也有更好的自動呼叫的方法,就是利用layoutSubviews

```

//自定義的UICollectionView

class DynamicCollectionView: UICollectionView {

override func layoutSubviews() {

super.layoutSubviews()

//此處加判斷如果相等就不更新size

if !CGSizeEqualToSize(self.bounds.size, intrinsicContentSize()) {

invalidateIntrinsicContentSize()

}

}

override func intrinsicContentSize() -> CGSize {

//這裡返回自定義的UICollectionView自己的屬性contentSize

return self.contentSize

}

}

```

>這樣的話每當UICollectionView內部的內容發生改變,他都會自己適應內容的大小達到自適應的目的.當然前提是不能新增高度的約束,新增了高度約束intrinsicContentSize會失效啊,當然你也可以自定義UILabel等,只要有intrinsicContentSize屬性的都可以設定自動適應的能力。

## 注意:

>還有當我們使用自己自定義的UICollectionView的時候,每當重新整理資料呼叫reloadData()方法的時候:

>務必呼叫 collectionViewLayout.invalidateLayout()方法,不然可能會發生下面的錯誤

```

UICollectionView received layout attributes for a cell with an index path that does not exist

```

當然,由於還沒有特別深入的瞭解寫的不是很詳細,其實還有很多有趣的屬性,比如:

invalidateItemsAtIndexPaths:

invalidateSupplementaryElementsOfKind:atIndexPaths:

invalidateDecorationElementsOfKind:atIndexPaths:

的:

invalidatedItemIndexPaths

invalidatedSupplementaryIndexPaths

invalidatedDecorationIndexPaths

等等有待研究。

可以的話關注下本人的部落格 PeachRain

相關文章