我试图用一对数组(一个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
}
}
答案 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
}