這次要把玩家1當成莊家,玩家2當成閒家,用Collection View 把每局誰贏做成一個圖表,並用Collection View內建的表頭(header)顯示勝率,預期效果如下
所以這次要用到的元件當然就是Collection View,不過我卻卡關了,一開始用Collection View Controller居然會當掉...我只好回到土法煉鋼,自己拉一個View Controller ,讓他符合UICollectionView 的 protocol。
雖然我有找到當掉的原因,但是我目前無法解釋,所以...我還是先用 View Controller 來做 Collection View
(本來是不想再教的啊!!!)
命名為RecordListCell,並繼承UICollectionViewCell類別
class RecordListCell: UICollectionViewCell {
}
就選擇剛剛自定義好的Class RecordListCell
PS:元件要選好,因為很多元件已經重疊,必要的時候可以在樹狀圖選擇
用藍線拖曳進class RecordListCell,分別命名為collctionHeader和recordImage
class RecordListCell: UICollectionViewCell {
@IBOutlet weak var collectionHeader: UILabel!
@IBOutlet weak var recordImage: UIImageView!
}
記得用逗號分隔
此時編譯會顯示錯誤,因為程式碼中尚未符合UICollectionViewDelegate, UICollectionViewDataSource的protocol
什麼是protocol可以參考
class RecordList: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
//...程式碼省略
}
在class RecordList中加入下方三個,缺一不可
var recordListInCollectionView: [String] = []
var winRate: String? = nil //這是給Header顯示勝率的變數
//共有幾個段落
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
//每個段落有幾個Item
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return recordListInCollectionView.count
}
//儲存格(cell)裡要顯示哪些資料
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let collectioncell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! RecordListCell //向下轉型,讓collectioncell可以擁有RecordListCell的屬性
collectioncell.recordImage.image = UIImage (named:recordListInCollectionView[indexPath.row])
return collectioncell
}
此外,因為我們需要利用儲存格的表頭顯示勝率,所以要另外呼叫func collectionView (viewForSupplementaryElementOfKind),程式碼如下
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at IndexPath: IndexPath) -> UICollectionReusableView {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader , withReuseIdentifier: "collectionHeader", for: IndexPath) as! RecordListCell
headerView.collectionHeader.text = winRate
return headerView
}
新增幾個變數
var winnerList: [String] = []
var makersNum = 0
var playersNum = 0
var drawNum = 0
在switch裡面加入一些判斷
switch checkWinner {
case let (x, y) where x == y:
drawNum += 1
winnerList.append("draw")
recordListInRps.append("Game \(gameRoundNum) 平手")
return winnerLabel.text = "平手"
case (0, 1):
makersNum += 1
winnerList.append("makers")
recordListInRps.append("Game \(gameRoundNum) winner is \(name1!)")
return winnerLabel.text = "\(name1!)獲勝"
case (0, 2):
playersNum += 1
winnerList.append("players")
recordListInRps.append("Game \(gameRoundNum) winner is \(name2!)")
return winnerLabel.text = "\(name2!)獲勝"
case (1, 0):
playersNum += 1
winnerList.append("players")
recordListInRps.append("Game \(gameRoundNum) winner is \(name2!)")
return winnerLabel.text = "\(name2!)獲勝"
case (1, 2):
makersNum += 1
winnerList.append("makers")
recordListInRps.append("Game \(gameRoundNum) winner is \(name1!)")
return winnerLabel.text = "\(name1!)獲勝"
case (2, 0):
makersNum += 1
winnerList.append("makers")
recordListInRps.append("Game \(gameRoundNum) winner is \(name1!)")
return winnerLabel.text = "\(name1!)獲勝"
case (2, 1):
playersNum += 1
winnerList.append("players")
recordListInRps.append("Game \(gameRoundNum) winner is \(name2!)")
return winnerLabel.text = "\(name2!)獲勝"
case (_, _): return
}
藉由segue把值傳到Collection View,這邊會用到之前定義的segue identifier: segue_rps_to_collection作為判斷切換的依據
if segue.identifier == "segue_rps_to_collection" {
let collection_VC = segue.destination as! RecordList
if winnerList != [] {
collection_VC.winRate = "makers: \(makersNum * 100 / gameRoundNum)% players: \(playersNum * 100 / gameRoundNum)% draw: \(drawNum * 100 / gameRoundNum)%"
collection_VC.recordListInCollectionView = winnerList
} else {
collection_VC.recordListInCollectionView = []
}
最後為了讓Table View也能快速看出誰勝誰負(只有文字實在太難非清楚誰勝),所以我們一樣加入圖片
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segue_rps_to_table" { //確認我們的動作頁面是切到tableView Controller
let table_VC = segue.destination as! RecordTable
if recordListInRps != [] {
table_VC.recordListInTableView = recordListInRps
table_VC.winnerListInTableView = winnerList // 這次加入的code
} else {
table_VC.recordListInTableView = ["比賽尚未開始"]
}
}
當然,相對應的Recordtable.swift也要新增
一個變數陣列來接收資料
var winnerListInTableView: [String] = []
改寫override func tableView(cellForRowAt indexPath:)
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let tablecell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
tablecell.textLabel?.text = recordListInTableView[indexPath.row]
//以下是改寫內容
guard winnerListInTableView != [] else { return tablecell}
tablecell.imageView?.image = UIImage (named: winnerListInTableView[indexPath.row])
//以上是改寫內容
return tablecell
}