聊天室列表

打開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即可看到上一個章節新增的聊天室房間,如圖

原始碼下載

results matching ""

    No results matching ""