昨天雖然把 collection view 可以 highl light 的效果做出來了。
但是還有幾個 bug 還沒解決
high light 的位置會隨 collection view 捲動的時候亂跳。
這個原因很簡單,跟之前使用 table view 顯示飲料數量一樣, collection view item 也是有 reusable 的記憶體管理。既然記憶體管理會錯亂,那我們就直接設一個陣列來管理 high light 的效果。
當我們滑動的 scroll view 逐漸離開 collection view item 的顯示區域時,collection view 不會跟著位移。
當我們預期水平移動 scroll view 的時候,整個 scroll view 會隨手指曲線移動,畫面的切換看起來會讓人頭暈目眩。
宣告一個新的陣列按順序來存放 high light 與否
var selectedBooling: [Bool] = []
在func collectionView(cellForItemAt indexPath: IndexPath) -> UICollectionViewCell中,把 high light 判斷改寫在這裡面。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! TitleCollectionVCCell
cell.titleLabel.text = menuList[indexPath.item]
// 初始先設定第一個 item 為已選取
if selectedBooling == [] {
selectedBooling.append(true)
for _ in 1...menuList.count {
selectedBooling.append(false)
}
}
// 判斷collection view 是否 high light
if selectedBooling[indexPath.item] {
cell.backgroundColor = UIColor.orange
} else {
cell.backgroundColor = UIColor.clear
}
return cell
}
改寫成:被點選的 item 其 high light 狀態管理陣列中的內容為 true,其餘為 false
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
for i in 0...(selectedBooling.count - 1) {
selectedBooling[i] = false
}
selectedBooling[indexPath.item] = true
menuCollectionView.reloadData()
// 點選 collection view item 後,跳轉 scroll view 到指定頁面
itemNum = CGFloat(indexPath.item)
showScrollView.setContentOffset(CGPoint(x: view.frame.width * itemNum, y: 0) , animated: true)
}
因為我們已經有狀態管理陣列,所以不用特別再去判斷 item 是否已經取消選取,所以整個 func 可以取消不用。
這邊有個小插曲,因為 UICollectionView 是 UIScrollView 的子類別,所以 collection view 在滑動的時候,也會調用 func scrollViewDidEndDecelerating,所以在使用 .scrollToItem 的屬性時,要先判斷 item 位置與 scroll view 位置是否不一致,不同的時候才去滾動 collection view
PS: 如果不加入這個判斷,當你滾動 collection view的時候,畫面會自動跳回來滾動前的位置
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageNum = Int(round(showScrollView.contentOffset.x / showScrollView.frame.size.width))
if pageNum != Int(itemNum) {
collectionView(menuCollectionView, didSelectItemAt: [0, pageNum])
menuCollectionView.scrollToItem(at: [0, pageNum], at:.centeredHorizontally, animated: true)
}
collectionView(menuCollectionView, didSelectItemAt: [0, pageNum])
}
點選 UIScrollView,在右側 Attributes 屬性頁面中將 Scroll View >> Scrolling >> Direction Lock Enabled 打勾
關於 UIScrollView 的屬性說明可以參考下方連結
UIScrollView的所有屬性和方法詳解