从Firebase中将成对的数组填充到tableView中,以仅显示前3个最高得分

时间:2018-12-04 01:31:12

标签: ios swift firebase uitableview

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

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
}
}

2 个答案:

答案 0 :(得分:1)

替换此功能:

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

答案 1 :(得分:1)

让我们将其分解为各个部分

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

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

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

var scoresArray = [ScoreClass]()

读取Firebase并填充数组的代码

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的标识符

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
}