带分段控制器的UITableView无法立即显示数据 - Swift

时间:2018-03-28 14:02:51

标签: swift tableview uisegmentedcontrol

我有一个Tab Bar Controller,其中两个视图之一是TableViewController。 TableViewController在表的顶部有一个SegmentedControl栏,用于在从Firebase中提取的两个数据集之间切换。

当我运行应用程序时,表格不会立即显示任何数据,只有当我切换到SegmentControl栏的其他部分时。但是,当我切换回来时,第一段的数据会加载。

我设置了一个断点来查看发生了什么,它正在跳过我编写的用于从Firebase中提取数据的代码,因此在初始加载时数组是空的,因此缺少数据。然而,当我将段切换到另一个选项时,数据会出现。

我也在尝试对数组中的数据进行排序,这根本不会做任何事情,因为它在数组返回空时运行,因此无需排序。

我的代码是:

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: { $0.score > $1.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: { $0.score > $1.score })

    DispatchQueue.main.async
    {
        self.leaderboardTable.reloadData()
    }

  }

  @IBAction func segmentedControlChanged(_ sender: Any)
  {
      DispatchQueue.main.async
      {
            self.leaderboardTable.reloadData()
      }
  }
}

我的问题是:

  1. 为什么数据不会立即加载?
  2. 如果阵列在第一次运行时没有填充数据,那么它们来自哪里?如果代码直接位于填充它们的代码之下,为什么不对它们进行排序?

1 个答案:

答案 0 :(得分:0)

调度块应该在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: { $0.score > $1.score })

    DispatchQueue.main.async
    {
        self.leaderboardTable.reloadData()
    }
})