基礎概念

  • Collection View
1. Collection view 可以顯示成網格狀,支持上下或左右滾動。
2. 可以設計每一項目的排列方式,自訂它們的大小和位置。
3. 這種視圖適合展示「照片牆」、「商品目錄」等需要大量資料展示的場景。
  • Collection View Cell
1. 每個 Cell 就是 Collection View 中的一個小方塊,用來展示資訊,如文字或圖片。
2. 滑動視圖時,Cell會根據需要重新出現,達到節省資源的效果。
  • Collection view layout
與 Table View 不同,Table View 元素只能一列一列地垂直顯示。
集合視圖的佈局可以動態變更,允許同樣的資料以不同的形式呈現。

1. Collection view layout 決定項目在螢幕上的位置和排列方式。
2. 可以隨時更換佈局,讓同一份資料以不同的方式呈現,比如列表、網格或其他自訂格式。
3. 這種佈局的靈活性使得 Collection view 能夠適應各種不同的顯示需求,而不必重新建立新的視圖。
  • Compositional Layout
1. Compositional Layout 能以更靈活的方法安排資料。
2. 因此可以將資料分成多個小項目,並將它們組合成群組和章節。
3. 可以指定每個部分的「具體大小」,或者「相對」於其他元素的大小。
4. 這種方式讓 App 可以有更多樣化的展示效果。
  • Flow Layout
1. Flow Layout 讓項目在集合視圖中像文字一樣排列成行或列。
2. 當一行或列滿了之後,項目會自動跳到下一行或列開始。
3. 這種佈局適合需要簡潔排列,如照片牆或是文字列表這類的展示方式。

1.Anatomy of a Collection View

1. Collection View 與 Table View 非常類似,它們遵循許多相同的架構原則。

2. 主要內容透過重複使用的 Cell 顯示,這些 Cell 是UICollectionViewCell的子類。

3. 使用 IndexPath 來定位 DataSource 和 Delegate 中的項目。
  • 開始建立 Collection View(建立一個只有單列項目的Collection View)
設置一個 BasicCollectionViewController。
  • 設計 Collection View Cell
1. 在Interface Builder中設置原型單元格,賦予 「Reuse Id」 為「Cell」並設置顏色。

2. 將 Label 置於 Cell 中央並設定約束,使其水平和垂直居中。

3. 設置 BasicCollectionViewCell 給予 UICollectionViewCell。
  • Outlet設置

2.Collection View Layouts

  • Layout 處理的差異:
  - Table View 自行計算Layout,形成一個線性的單元格列表。
- Collection View 依賴一個獨立的Layout實例來決定單元格的放置和大小。
  • Latout 的靈活性
雖然 Collection View 的 Layout 設計相對複雜,但它提供了更大的靈活性來呈現數據。
  • 默認Layout
在Storyboard中創建新的CollectionView時,預設會有一個Flow Layout 實例。
  • Layout的選擇
1. 雖然預設是 Flow layout,建議使用組合式佈局(compositional layout)。
2. 組合式佈局通過程式碼組合章節、群組和項目,提供了比流動佈局更大的彈性。

2–1.Simple Compositional Layout

官方教材
  • 開始設計Layout
在 BasicCollectionViewController 新增一個generateLayout方法。
  • 組合佈局(Compositional layout)的結構
組合式佈局由三部分構成:區段(Section)、群組(Group)和項目(Item)。

- 區段類似於表格視圖的章節,代表資料的最上層結構。
- 群組是容納單元格的容器,通常用於直的或橫的排列。
- 項目則是最基本的單位,相當於表格視圖的單元格,代表一個資料模型。
  • 設置

1. 設定 Item 大小:
- 確定 Item 要「滿版佔據」 Group 的寬高,然後建立 NSCollectionLayoutItem。

2. 建立 Group:
- Group 的大小設為跟 Section 一樣寬,高度為固定70。
- 用這個大小設定創建一個水平 Group,每個 Group 包含一個 Item 。

3. 建立 Section 和 Layout:
- 使用剛建立的 Group 來創造一個 Section。
- 把這個 Section 放進一個新的Layout裡,然後回傳這個Layout。

4. 指定 CollectionView 使用新Layout:
- 在 viewDidLoad 設定 CollectionView 使用 generateLayout 生成的Layout。

5. 清理多餘程式碼:
- 確保viewDidLoad方法中只有調用父類的方法和設置新佈局的程式碼。
- 移除collectionView.register(_:forCellWithReuseIdentifier:)。

2–2.Collection View Data Source

  • 要讓Collection View顯示資料,需要設定 Data Source。
  • 新增資料陣列
1. 新增一個日本都道府縣的資料陣列(japanPlaceItems)。
2. japanPlaceItems 設為private 因為只會在BasicCollectionViewController
這個檔案裡用到,別的地方不會用到它。
  • UICollectionViewDataSource實作:
1. 由於繼承了UICollectionViewController,已預設 UICollectionViewDataSource。
2. 不需實作 numberOfSections(in:),因為只有一個 Section。
3. collectionView(_:numberOfItemsInSection:) 設定每個 Section 的 Item 數量。
  • 配置 Cell
實作collectionView(_:cellForItemAt:),
用自定義 BasicCollectionViewCell,設定顯示的文字為 japanPlaceItems 陣列中對應的地名。
  • 顯示部分
整個cell連再一起

2–3.Cell Spacing

  • 設定間距值:
在 generateLayout 方法中,定義一個 spacing,用來確保 Item 之間的間距均勻且容易調整。
  • 設置 group 間距:
在設定 group 配置之後,使用 contentInsets 給 group 加上間距,
這樣可以確保 cell 與其他物件或佈局邊緣之間有一定的空間。
NSDirectionalEdgeInsets
  • 測試

2–4.Rotation

  • 自動調整 Cell:
當螢幕寬度改變後, Cell 會自動調整以適應新的寬度。
  • Flow Layout 的自動調整:
流動佈局(Flow Layout)能提供基本的自適應行為,使Cell在螢幕旋轉後依然合理排列。
  • Compositional Layout 的優點:
Compositional Layout 在自動保持佈局意圖上更為強大,不需要自定義程式碼來應對像設備方向
這樣的環境變化。

Lab — Emoji Dictionary

  • 用之前練習Emoji Dictionary的TableView,將其改為使用Collection View。

1.Cell Setup

  • 設置storyboard的collectionView
參照先前TableView的介面替CollectionView設置相同排版。
- CollectionView,將Items從0改為1。
- 將Cell id 設為「Item」。
- 自訂的EmojiCollectionViewCell,並連接相應的UI元素到它的outlets。
- 設置cell的segue,點擊後進入到AddEditEmojiTableViewController。

2.Complete the View Controller

  • 設定Cell大小:
在EmojiCollectionViewController的viewDidLoad方,設定每個cell的大小,
讓它們各自填滿其容器。

1. 建立 group 代表每一行:
- 每一行用一個 group 來表示,設定 group 的高度為70點,寬度與容器一樣寬。
- 確保每個 group 只包含一個 Item 。

2. 將 group 封裝進 section:
- 把剛建立的 group 包裝成一個 section,用這個 section 來創建collectionView的最終組合式佈局。

3. 設定collectionView的佈局:
- 最後,使用剛剛建立的 section 來設定集合視圖的組合式佈局。

2–1.Update/Insert Changes

  • 更新或新增資料處理的步驟
  • 處理返回的動作:
檢查unwindToEmojiTableView,這裡會根據從集合視圖回傳的資料和segue的來源控制器,
判斷是要更新還是新增一個表情符號。
  • 更新現有表情符號:
如果 collectionVIew 的indexPathsForSelectedItems屬性有數據,
表示有一個項目被選擇並編輯了。
這時,需要更新該項目的定義以及顯示的細節,以反映這些變更。
  • 新增表情符號:
如果沒有選擇的索引路徑,意味著創建一個新的表情符號,它的定義需要被添加到你的表情符號陣列中。
同時,collectionVIew 也需要增加一個新的行來顯示它。

2–2.Handle Deletes

  • 處理 CollectionView 中 Item 的刪除不同於 TableView,因為它沒有內建的刪除機制。
為集合視圖的項目定義了一個上下文選單,當用戶長按項目時,會彈出一個含有「刪除」選項的選單。
如果用戶選擇「刪除」,則會調用deleteEmoji方法來從數據源和視圖中移除該項目。
  • 加入上下文選單::
為CollectionView中的項目添加上下文菜單,
需要實作collectionView(_:contextMenuConfigurationForItemAt:point:)方法,
這是UICollectionViewDelegate的一部分。
這樣用戶長按項目時就會出現選單。
  • 實作刪除功能:
在類定義的底部添加方法實作。這個方法會定義一個包含單一動作的UIMenu,這個動作就是刪除功能。
  • 建立刪除動作:
設置 deleteEmoji方法,當用戶選擇刪除動作時,這個方法會從數據源刪除對應的表情,
並且從集合視圖中移除該項目。
  • 測試

--

--

wei Tsao 學習紀錄
彼得潘的 Swift iOS / Flutter App 開發教室

Hi ! 我是wei , 先前未接觸過程式開發設計,想藉此來記錄自己的學習歷程,以利培養自己的程式邏輯 :)