# 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