設定 flow layout 的 collection cell & 間距固定大小

比方想讓 cell 固定大小 102 * 102,實現以下的照片牆頁面,我們有三種設定 cell 大小的方法:

ps: 對 collection view 程式不熟的朋友可先參考以下連結,了解 collection view 程式的基本寫法。

方法1: 從 Interface Builder 設定 cell 大小和間距

將 Estimate Size 設為 None,將 width & height 設為 102。記得 Estimate Size 要設為 None,cell 大小才會乖乖依據 Width & Height 的設定。

在 iPhone 14 Pro Max 執行 App

collection view 裡的 cell 大小果然都聽話地變成 100 * 100 了。不過在 iPhone 14 Pro Max 上為什麼一排只有 3 張圖片呢 ? 14 Pro Max 的寬度是 430,應該可以塞 4 張圖片呀。

因為我們少考慮了一個東西,cell 之間的間距。請點選 collection view,切到 Size inspector 頁面,看到下圖紅色框框標示的 Min Spacing 欄位。

  • Min Spacing For Cells

當 collection view 是上下捲動(flow layout 的 Scroll Direction 是 vertical),cell 將由左而右水平排列,排完再排下一列,Min Spacing For Cells 代表同一排(row) cell 間的最小間距。

當 collection view 是左右捲動(flow layout 方向是 Horizontal),cell 將由上而下排列,排完再往右排下一列,Min Spacing For Cells 代表同一列(column) cell 間的最小間距。

  • Min Spacing For Lines

當 collection view 是上下捲動(flow layout 方向是 vertical),Min Spacing For Lines 代表同一列(column) cell 間的最小間距。

當 collection view 是左右捲動(flow layout 方向是 Horizontal),Min Spacing For Lines 代表同一排(row) cell 間的最小間距。

剛剛 collection view 預設的 min spacing for cells 是 10,因此在寬度 430 的 iPhone 14 Pro Max 上只能塞一排 3 張圖片。如果放 4 張圖片,它們合起來的寬度是 408(102*4),但它們之間有 3 個間距,所以間距至少佔 30,加起來 438 就超過 430 了。

如果想要一排顯示 4 張照片,我們可以將 Min Spacing For Cells 調小,比方將它調為 1。

結果

成功一排顯示 4 張圖片了。

方法2: 從程式設定 cell 大小和間距

在 viewDidLoad 裡設定 cell 的大小和間距。

override func viewDidLoad() {
super.viewDidLoad()
configureCellSize()
}

func configureCellSize() {
let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout
flowLayout?.itemSize = CGSize(width: 100, height: 100)
flowLayout?.estimatedItemSize = .zero
flowLayout?.minimumInteritemSpacing = 1
}

說明

let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout

UICollectionViewController 的 property collectionViewLayout 的型別為 UICollectionViewLayout,由於我們在 storyboard 將 Layout 設為 Flow ,因此我們可將它轉型為 UICollectionViewFlowLayout,之後再透過它的 property 設定 cell 的大小和間距。

ps: 若是另外將 collection view 加到 view controller 的 view,沒有使用 UICollectionViewController,則要從 collection view 讀取 property collectionViewLayout。

flowLayout?.itemSize = CGSize(width: 102, height: 102)

設定 itemSize 控制 cell 的尺寸。

flowLayout?.estimatedItemSize = .zero

將 estimatedItemSize 設為 .zero,如此 cell 的尺寸才會依據 itemSize,否則它將從 auto layout 的條件計算 cell 的尺寸。

flowLayout?.minimumInteritemSpacing = 1

minimumInteritemSpacing 控制 Min Spacing For Cells。minimumLineSpacing 控制 Min Spacing For Lines。

方法3: 設定固定大小的 auto layout 條件

讓 collection view 使用 auto layout 自動計算 cell 大小,比方設定圖片寬高 102 的 auto layout 條件,並讓圖片和 content view 的間距為 0,如此 cell 的大小將自動變成 102 * 102。

從 Interface Builder 將 collection view 的 Estimate Size 設為 Automatic,讓它以 auto layout 計算大小。

我們也可從程式設定 Estimate Size,透過將 UICollectionViewFlowLayout 物件的 estimatedItemSize 設為 UICollectionViewFlowLayout.automaticSize。

let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout
flowLayout?.estimatedItemSize = UICollectionViewFlowLayout.automaticSize

設定圖片寬高 102 的 auto layout 條件,並讓圖片和 content view 的間距為 0。

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com