带分段控制器的 UITableView 不立即显示数据 - Swift
UITableView with Segmented Controller not displaying data immediately - Swift
我有一个 Tab Bar Controller,它的两个视图之一是 TableViewController。 TableViewController 在 table 的顶部有一个 SegmentedControl 栏,用于在从 Firebase 提取的两个数据集之间切换。
当我 运行 应用程序时,table 不会立即显示任何数据,只有当我切换到 SegmentControl 栏的另一部分时才显示。但是,当我切换回来时,第一段的数据加载。
我设置了一个断点以查看发生了什么,它跳过了我为从 Firebase 中提取数据而编写的代码,因此数组在初始加载时为空,因此缺少数据。然而,当我将段切换到另一个选项时,数据出现了。
我也在尝试对数组中的数据进行排序,但这根本没有做任何事情,因为它 运行s 当数组返回为空时,所以没有什么可排序的。
我的代码是:
class LeaderboardViewController: UITableViewController
{
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet var leaderboardTable: UITableView!
var countyRef = Database.database().reference().child("countyleaderboard")
var schoolRef = Database.database().reference().child("schoolleaderboard")
var refHandle: UInt!
var countyList = [County]()
var schoolList = [School]()
override func viewDidLoad()
{
super.viewDidLoad()
fetchData()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var sectionCount = 0
switch(segmentedControl.selectedSegmentIndex)
{
case 0:
sectionCount = countyList.count
break
case 1:
sectionCount = schoolList.count
break
default:
break
}
return sectionCount
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let boardCell = tableView.dequeueReusableCell(withIdentifier: "boardCell", for: indexPath)
switch(segmentedControl.selectedSegmentIndex)
{
case 0:
boardCell.textLabel!.text = "" + countyList[indexPath.row].name! + ": \(countyList[indexPath.row].score!)"
break
case 1:
boardCell.textLabel!.text = "" + schoolList[indexPath.row].name! + ": \(schoolList[indexPath.row].score!)"
break
default:
break
}
return boardCell
}
func fetchData()
{
schoolRef.observe(.childAdded, with:
{ snapshot in
if let dictionary = snapshot.value as? [String: AnyObject]
{
let school = School()
school.name = dictionary["name"] as! String
school.score = dictionary["score"] as! Float
self.schoolList.append(school)
}
}, withCancel: nil)
self.schoolList.sort(by: { [=11=].score > .score })
countyRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children
{
let snap = child as! DataSnapshot
let county = County()
county.name = snap.key as String
county.score = snap.value as! Float
self.countyList.append(county)
}
})
self.countyList.sort(by: { [=11=].score > .score })
DispatchQueue.main.async
{
self.leaderboardTable.reloadData()
}
}
@IBAction func segmentedControlChanged(_ sender: Any)
{
DispatchQueue.main.async
{
self.leaderboardTable.reloadData()
}
}
}
我的问题是:
- 为什么数据没有立即加载?
- 如果第一个 运行 没有用数据填充数组,那么数组来自哪里?如果该代码直接位于填充它们的代码下方,为什么不对它们进行排序?
调度块应该在for循环之后和})
之前。
它应该在 observe
/observeSingleEvent
范围内。此外,您的 sort
代码需要位于同一块内。如下所示:
countyRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children
{
let snap = child as! DataSnapshot
let county = County()
county.name = snap.key as String
county.score = snap.value as! Float
self.countyList.append(county)
}
self.countyList.sort(by: { [=10=].score > .score })
DispatchQueue.main.async
{
self.leaderboardTable.reloadData()
}
})
我有一个 Tab Bar Controller,它的两个视图之一是 TableViewController。 TableViewController 在 table 的顶部有一个 SegmentedControl 栏,用于在从 Firebase 提取的两个数据集之间切换。
当我 运行 应用程序时,table 不会立即显示任何数据,只有当我切换到 SegmentControl 栏的另一部分时才显示。但是,当我切换回来时,第一段的数据加载。
我设置了一个断点以查看发生了什么,它跳过了我为从 Firebase 中提取数据而编写的代码,因此数组在初始加载时为空,因此缺少数据。然而,当我将段切换到另一个选项时,数据出现了。
我也在尝试对数组中的数据进行排序,但这根本没有做任何事情,因为它 运行s 当数组返回为空时,所以没有什么可排序的。
我的代码是:
class LeaderboardViewController: UITableViewController
{
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet var leaderboardTable: UITableView!
var countyRef = Database.database().reference().child("countyleaderboard")
var schoolRef = Database.database().reference().child("schoolleaderboard")
var refHandle: UInt!
var countyList = [County]()
var schoolList = [School]()
override func viewDidLoad()
{
super.viewDidLoad()
fetchData()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var sectionCount = 0
switch(segmentedControl.selectedSegmentIndex)
{
case 0:
sectionCount = countyList.count
break
case 1:
sectionCount = schoolList.count
break
default:
break
}
return sectionCount
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let boardCell = tableView.dequeueReusableCell(withIdentifier: "boardCell", for: indexPath)
switch(segmentedControl.selectedSegmentIndex)
{
case 0:
boardCell.textLabel!.text = "" + countyList[indexPath.row].name! + ": \(countyList[indexPath.row].score!)"
break
case 1:
boardCell.textLabel!.text = "" + schoolList[indexPath.row].name! + ": \(schoolList[indexPath.row].score!)"
break
default:
break
}
return boardCell
}
func fetchData()
{
schoolRef.observe(.childAdded, with:
{ snapshot in
if let dictionary = snapshot.value as? [String: AnyObject]
{
let school = School()
school.name = dictionary["name"] as! String
school.score = dictionary["score"] as! Float
self.schoolList.append(school)
}
}, withCancel: nil)
self.schoolList.sort(by: { [=11=].score > .score })
countyRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children
{
let snap = child as! DataSnapshot
let county = County()
county.name = snap.key as String
county.score = snap.value as! Float
self.countyList.append(county)
}
})
self.countyList.sort(by: { [=11=].score > .score })
DispatchQueue.main.async
{
self.leaderboardTable.reloadData()
}
}
@IBAction func segmentedControlChanged(_ sender: Any)
{
DispatchQueue.main.async
{
self.leaderboardTable.reloadData()
}
}
}
我的问题是:
- 为什么数据没有立即加载?
- 如果第一个 运行 没有用数据填充数组,那么数组来自哪里?如果该代码直接位于填充它们的代码下方,为什么不对它们进行排序?
调度块应该在for循环之后和})
之前。
它应该在 observe
/observeSingleEvent
范围内。此外,您的 sort
代码需要位于同一块内。如下所示:
countyRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children
{
let snap = child as! DataSnapshot
let county = County()
county.name = snap.key as String
county.score = snap.value as! Float
self.countyList.append(county)
}
self.countyList.sort(by: { [=10=].score > .score })
DispatchQueue.main.async
{
self.leaderboardTable.reloadData()
}
})