聊天室列表
打開RoomListViewController.swift,在override func viewDidLoad()上方加入
var roomListTableView: UITableView!
var rooms = [[String: String]]()
在程式碼尾端(不在任何括號內)加入下列程式
extension RoomListViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// TODO: 暫時,稍後實作
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// TODO: 暫時,稍後實作
return UITableViewCell()
}
}
此處為擴充RoomListViewController並實作UITableViewDelegate, UITableViewDataSource以便稍後可以被tableView使用,善用extension可將程式碼不同用途的部分拆開成數個部分,增加可讀性以及更方便維護
(實作的兩個func是必須的,如果不寫Xcode會報錯)
在func setupUI()函式內部最下方追加下列程式
func setupUI() {
// ... 上方省略
// --- 以下為增加程式碼 ---
roomListTableView = UITableView(frame: .zero, style: .plain)
roomListTableView.delegate = self
roomListTableView.dataSource = self
// 設定Layout
view.addSubview(roomListTableView)
roomListTableView.translatesAutoresizingMaskIntoConstraints = false
roomListTableView.topAnchor.constraint(equalTo: bar.bottomAnchor).isActive = true
roomListTableView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true
roomListTableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
roomListTableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
// 註冊稍後要使用的Cell型別
roomListTableView.register(UITableViewCell.self, forCellReuseIdentifier: "RoomCell")
}
在func viewDidLoad()中roomsRef = FIRDatabase.database().reference().child("rooms")之後加入下列程式
// 觀察房間是否有增加
roomsRef.observe(.childAdded, with: {[weak self] (snapshot) in
let roomID = snapshot.key
if let roomData = snapshot.value as? [String: String] {
var data = roomData
data["id"] = roomID
// 以下順序重要
// 1. 先對 datasource 進行操作
self?.rooms.append(data)
let lastIndex = (self?.rooms.count ?? 0) - 1
guard lastIndex >= 0 else { return }
// 2. 告知tableView開始更新
self?.roomListTableView.beginUpdates()
// 3. 進行更新 (除了insert,另外還有 delete 和 update 可以進行操作)
self?.roomListTableView.insertRows(at: [IndexPath(row: lastIndex, section: 0)], with: UITableViewRowAnimation.automatic)
// 4. 告知tableView結束更新
self?.roomListTableView.endUpdates()
}
})
在override func didReceiveMemoryWarning()上方加入
deinit {
roomsRef.removeAllObservers()
}
如此可以在RoomListViewController被釋放前先釋放所有的reference所有的觀察行為(Observe),否則APP可能因此而Crash
改寫extension中的兩個func
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rooms.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 使用先前註冊的Cell名稱取出可重複使用的Cell
let cell = tableView.dequeueReusableCell(withIdentifier: "RoomCell", for: indexPath)
cell.selectionStyle = .none
cell.textLabel?.text = rooms[indexPath.row]["name"]
return cell
}
運行APP即可看到上一個章節新增的聊天室房間,如圖
原始碼下載