将一组对填充到 Firebase 的 tableView 中以仅显示前 3 个最高分 [英] Populating an array of pairs into a tableView from Firebase to display only the top 3 highest scores

查看:21
本文介绍了将一组对填充到 Firebase 的 tableView 中以仅显示前 3 个最高分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用一对数组(一个 Int,一个 String)填充我的 tableView.不幸的是,我在理解为什么它不起作用时遇到了一些麻烦,因为我似乎无法填充 tableView,我收到 indexOutOfRange 作为错误.我使用 firebase 作为我的数据库来检索我想要填充的数据.请看下面....

I am trying to populate my tableView with an array of pairs (one Int, one String). Unfortunately I am having some trouble understanding why it is not working as I can't seem to make the tableView populate, I receive indexOutOfRange as an error. I am using firebase as my database to retrieve the data I would like to populate. Please see below....

class Leaderboard: UIViewController, UITableViewDataSource, UITableViewDelegate {

private let padding = 12

private var quiz: Quiz!
private let backgroundImageView = UIImageView()
private let contentView = UIView()
private let leaderboardLabel = UILabel()
private let rankLabel = UILabel()
private let userLabel = UILabel()
private let scoreLabel = UILabel()
private let tableViewCellHeight: CGFloat = 60
private let bottomButton = BottomBorderedButtons()

var scoresArray = [ScoreClass]()

var topScoresTableView: UITableView = {
    let tableView = UITableView()
    return tableView
}()

override func viewDidLoad() {
    super.viewDidLoad()
    retrieveUserData()
    setupViews()
}

required init(quiz: Quiz) {
    super.init(nibName: nil, bundle: nil)
    defer {
        self.quiz = quiz
    }
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
 }

class ScoreClass {

var name = ""
var score = 0

init(withName: String, andScore: Int) {
    name = withName
    score = andScore
  }
}

let ref = Database.database().reference()

func retrieveUserData() {

    let postsRef = self.ref.child("Users")
    let query = postsRef.queryOrdered(byChild: "highscore").queryLimited(toLast: 3)
    query.observeSingleEvent(of: .value, with: { snapshot in
        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let dict = snap.value as! [String: Any]
            let name = dict["username"] as! String
            let score = dict["highScore"] as! Int
            let aScore = ScoreClass(withName: name, andScore: score)
            self.scoresArray.insert(aScore, at: 0)
        }

        for s in self.scoresArray {
            print(s.score, s.name)
        }
    })
        self.topScoresTableView.reloadData()
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    var countarr = 0
    for s in self.scoresArray {
        countarr = s.name.count
        print(s.score, s.name)
        print(countarr)
    }
    return countarr
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = topScoresTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
    let scoreClassObject = scoresArray[indexPath.row]
    let name = scoreClassObject.name
    let score = scoreClassObject.score
    cell.backgroundColor = UIColor.clear
    cell.usernameLabel.text = name
    cell.resultLabel.text = String(score)
    cell.rankNumberLabel.text = "\(indexPath.row + 1)"
    print(scoresArray)
    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 44
}

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return 10.0
}

func setupViews() {
    view.addSubview(backgroundImageView)
    backgroundImageView.addSubview(contentView)
    contentView.addSubview(leaderboardLabel)
    contentView.addSubview(rankLabel)
    contentView.addSubview(userLabel)
    contentView.addSubview(scoreLabel)
    contentView.addSubview(topScoresTableView)
    contentView.addSubview(bottomButton)

    self.backgroundImageView.snp.makeConstraints { (make) in
        make.top.equalTo(topLayoutGuide.snp.bottom)
        make.leading.equalToSuperview()
        make.trailing.equalToSuperview()
        make.bottom.equalToSuperview()
    }

    self.backgroundImageView.contentMode = UIViewContentMode.scaleAspectFill
    self.backgroundImageView.isUserInteractionEnabled = true
    self.backgroundImageView.image = UIImage(named: "Stars.png")

    self.contentView.snp.makeConstraints { (make) in
        make.edges.equalToSuperview()
    }

    contentView.backgroundColor = transluscentGrey

    self.leaderboardLabel.snp.makeConstraints { (make) in
        make.top.equalToSuperview()
        make.leading.equalToSuperview()
        make.trailing.equalToSuperview()
        make.bottom.equalTo(topScoresTableView.snp.top).offset(-50)
        make.centerX.equalToSuperview()
    }

    leaderboardLabel.textAlignment = .center
    leaderboardLabel.numberOfLines = 0
    leaderboardLabel.textColor = .white
    leaderboardLabel.font = UIFont.boldSystemFont(ofSize: 28.0)
    leaderboardLabel.text = "Leaderboard"
    leaderboardLabel.backgroundColor = tableViewCell

    self.rankLabel.snp.makeConstraints { (make) in
        make.top.equalTo(leaderboardLabel.snp.bottom).offset(10)
        make.leading.equalToSuperview().offset(padding)
        make.height.equalTo(30)
    }

    rankLabel.textAlignment = .center
    rankLabel.numberOfLines = 0
    rankLabel.baselineAdjustment = .alignCenters
    rankLabel.textColor = .white
    rankLabel.font = UIFont(name: "SFUIDisplay-Medium", size: 3)

    rankLabel.layer.cornerRadius = 5.0
    rankLabel.clipsToBounds = true
    rankLabel.text = "Rank"

    self.userLabel.snp.makeConstraints { (make) in
        make.top.equalTo(leaderboardLabel.snp.bottom).offset(10)
        make.leading.equalTo(rankLabel.snp.trailing).offset(padding)
        make.height.equalTo(30)
        make.width.equalToSuperview().multipliedBy(0.50)
    }

    userLabel.textAlignment = .center
    userLabel.numberOfLines = 0
    userLabel.baselineAdjustment = .alignCenters
    userLabel.textColor = .white
    userLabel.font = UIFont(name: "SFUIDisplay-Medium", size: 3)
    userLabel.layer.cornerRadius = 5.0
    userLabel.clipsToBounds = true
    userLabel.text = "Username"

    self.scoreLabel.snp.makeConstraints { (make) in
        make.top.equalTo(leaderboardLabel.snp.bottom).offset(10)
        make.leading.equalTo(userLabel.snp.trailing).offset(padding)
        make.height.equalTo(30)
        make.trailing.equalToSuperview().offset(-padding)
    }

    scoreLabel.textAlignment = .center
    scoreLabel.numberOfLines = 0
    scoreLabel.baselineAdjustment = .alignCenters
    scoreLabel.textColor = .white
    scoreLabel.font = UIFont(name: "SFUIDisplay-Medium", size: 3)
    scoreLabel.layer.cornerRadius = 5.0
    scoreLabel.clipsToBounds = true
    scoreLabel.text = "Score"

    self.topScoresTableView.snp.makeConstraints { (make) in
        make.leading.equalToSuperview()
        make.trailing.equalToSuperview()
        make.height.equalToSuperview().multipliedBy(0.65)
        make.bottom.equalToSuperview().offset(-30)
    }

    topScoresTableView.delegate = self
    topScoresTableView.register(TableViewCell.self, forCellReuseIdentifier: "cell")
    topScoresTableView.dataSource = self
    topScoresTableView.backgroundColor = UIColor.clear

    self.bottomButton.snp.makeConstraints { (make) in
        make.top.lessThanOrEqualTo(topScoresTableView.snp.bottom).offset(5)
        make.width.equalTo(60)
        make.bottom.equalToSuperview().offset(-5)
        make.centerX.equalToSuperview()
    }
    self.bottomButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
    self.bottomButton.backgroundColor = .yellow
}
}

推荐答案

让我们把它分解成几个部分

Let's decompose this into it's parts

从 Firebase 填充并保存名称和分数的 ScoreClass 对象

The ScoreClass objects which are populated from Firebase and hold the name and score

class ScoreClass {
   var name = ""
   var score = 0
   init(withName: String, andScore: Int) {
      name = withName
      score = andScore
   }
}

保存用作 tableView 数据源的 ScoreClass 对象的数组

The array to hold the ScoreClass objects that is used as the dataSource for tableView

var scoresArray = [ScoreClass]()

读取 Firebase 并填充数组的代码

The code to read Firebase and fill the array

func getScoresAndNamesFromFirebaseAndStuffIntoArray() {
    let postsRef = self.ref.child("Users")
    let query = postsRef.queryOrdered(byChild: "highscore").queryLimited(toLast: 3)
    query.observeSingleEvent(of: .value, with: { snapshot in
        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let dict = snap.value as! [String: Any]
            let name = dict["username"] as! String
            let score = dict["highScore"] as! Int
            let aScore = ScoreClass(withName: name, andScore: score)
            self.scoresArray.insert(aScore, at: 0)
        }
        self.topScoresTableView.reloadData()
    })     
}

然后是 tableView 委托方法.有三个函数来处理 tableView.这假设您在 tableView 中的文本单元格的标识符为 NameScoreCell

and then the tableView delegate methods. There are three functions to handle the tableView. This assumes your text cell in the tableView has an identifier of NameScoreCell

let textCellIdentifier = "NameScoreCell"

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return scoresArray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: textCellIdentifier, for: indexPath as IndexPath)

    let row = indexPath.row
    let scoreObject = scoresArray[row]
    let score = scoreObject.score
    let name = scoreObject.name
    cell.nameLabel?.text = name
    cell.scoreLabel?.text = score

    return cell
}

这篇关于将一组对填充到 Firebase 的 tableView 中以仅显示前 3 个最高分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆