【问题标题】:UITableView Swift questionsUITableView Swift 问题
【发布时间】:2015-05-21 20:26:09
【问题描述】:

我想使用 Parse 进行查询以将字符串添加到数组中。然后我想将这些字符串放入我的 UITableView 的单元格中。但是,每次我运行该应用程序时,我的桌子上似乎都没有出现任何内容。如果有人可以帮助解释它可能不会出现的一些原因,这是我的代码

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate  {

@IBOutlet weak var tableView: UITableView!


var friendsArray: [String] = []

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")

    var usrname = currentUser?.username
    var query = PFQuery(className:"Relation")
    query.whereKey("Sender", equalTo : usrname!)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in

        if error == nil {
            // The find succeeded.
            //println("Successfully retrieved \(objects) scores.")
            // Do something with the found objects
            if let objects = objects as? [PFObject] {
                for object in objects {
                    var friendName = object["Friend"] as! String
                    println(friendName)
                    self.friendsArray.append(friendName)
                }
            }
        }
        else {
            // Log details of the failure
            println("Error: \(error!) \(error!.userInfo!)")
        }
    }


}


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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell

    cell.textLabel?.text = self.friendsArray[indexPath.row]

    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

}

【问题讨论】:

    标签: ios uitableview swift parse-platform


    【解决方案1】:

    您需要在findObjectsInBackground: 调用的完成块中调用[self.tableView reloadData];

    【讨论】:

      【解决方案2】:

      if error == nil{...} 语句的末尾,像这样加载表数据:

      if error == nil{
        //All that other stuff...
        tableView.reloadData()
      }
      

      还要确保您的tableView 将其delegatedatasource 连接到您的视图控制器。这可能需要将其放入viewDidLoad

      tableView.delegate = self
      tableView.datasource = self
      

      我还发现您的 tableView 被声明为 weak 很奇怪,但这可能不相关。

      试试这些方法,如果您仍然遇到问题,请告诉我们。祝你好运! :)

      【讨论】:

      • weak,因为它是直接从他的xib文件中引用的IBOutlet
      【解决方案3】:

      应用程序不知道您的数据何时返回,因此您必须在成功接收数据后显式刷新 UITableView。稍后使用[self.tableView reloadData] 重新加载UITableView

      UITableView 只会在 UIViewController 加载时加载一次。除非,您已经拥有 UIViewController 加载时间的数据。否则,第一次行数为0,不会调用委托方法cellForRowAtIndexPath

      findObjectsInBackgroundWithBlock 是一个异步调用,当您查看文档时。它不像它的字面意思是在后台运行。这意味着它不会阻塞当前线程,以便用户仍然可以与应用程序进行交互。

      【讨论】:

      • @Kasik Async 表示它不会等待响应返回到当前线程。这并不意味着它被分派到另一个线程。
      【解决方案4】:

      当您调用 findObjectsInBackgroundWithBlock 时,它会按照它的名称进行操作,特别是在后台运行。

      同时,当它在后台运行时,您的表格视图代码继续在前台运行,有效地并行。

      所以你的viewDidLoad 函数将退出,接下来会调用numberOfRowsInSection,但此时如果findObjectsInBackgroundWithBlock 尚未完成,那么friendsArray.count 将为0。

      【讨论】:

      • 那么我该怎么做才能解决这个问题?
      • 昨天与同样的问题类似。他们在与您不同的地方使用异步代码。 stackoverflow.com/questions/30361517/…。原理和方案选择类似。
      • 我很困惑如何确保在 ViewdidLoad 之后运行 CellforRowAtIndexPath 函数,因为我认为 ViewDidLoad 甚至 ViewDidAppear 都会首先发生
      • 在您的情况下,当块完成时,您可以刷新表格。
      • 我该怎么做?
      【解决方案5】:

      试试这些东西。它会帮助你 获得元素数组后,请重新加载 uitableView。 如果您使用情节提要,请检查数据源插座 如果你没有使用故事板或 xib,那么你在编码 wisse 中设置数据源

      【讨论】:

        【解决方案6】:

        你可以这样使用

        public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
        
        {
        
        
            let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell")! as UITableViewCell
        
        
            cell.textLabel?.text = app.str[indexPath.row]
        
        
        
        
             print(" cell \(cell.textLabel?.text!)")
        
        
            return cell
        
        
        }
        

        TableOutLet.reloadData()

        【讨论】:

          【解决方案7】:
          • super.viewDidLoad() 之后的 viewDidLoad() 中写入以下两行,使您的 tableView 与其委托和数据源一致:

            tableView.datasource = self tableView.delegate = self

          • 然后更新此代码如下:

            如果让对象=对象为? [PF对象] { 对象中的对象{ var friendName = object["Friend"] as!细绳 println(朋友姓名) self.friendsArray.append(friendName) } tableView.reloadData() }

          • 之后在 tableView 委托方法中为 numberOfRows() 方法返回 self.friendsArray.count 并将您的代码也放入 cellForRow 中。

          【讨论】:

            【解决方案8】:

            在数组中追加元素后放置你的行。

            override func viewDidLoad() {
            super.viewDidLoad()
            
            
            var usrname = currentUser?.username
            var query = PFQuery(className:"Relation")
            query.whereKey("Sender", equalTo : usrname!)
            query.findObjectsInBackgroundWithBlock {
                (objects: [AnyObject]?, error: NSError?) -> Void in
            
                if error == nil {
                    // The find succeeded.
                    //println("Successfully retrieved \(objects) scores.")
                    // Do something with the found objects
                    if let objects = objects as? [PFObject] {
                        for object in objects {
                            var friendName = object["Friend"] as! String
                            println(friendName)
                            self.friendsArray.append(friendName)
                        }
                    }
                }
                else {
                    // Log details of the failure
                    println("Error: \(error!) \(error!.userInfo!)")
                }
            }
            self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
            }
            

            或者您可以在最终数组更新后重新加载表格

            【讨论】:

              【解决方案9】:

              正如另一个提示所提到的,您需要调用 reloadData 但您需要在主线程中调用它才能尽快看到结果

              dispatch_async(dispatch_get_main_queue()) {self.tableView.reloadData()}
              

              【讨论】:

              • 他没有将该代码块分派到另一个队列,它只是在主线程上运行。所以,self.tableView.reloaddata() 就够了
              • @LucasHuang 我不知道 PFQuery 但 findInBackground 在我看来不像主线程。它可以通过在主线程上执行回调的方式来实现,但这是不寻常的。另一方面,使用 dispatch_async 几乎是免费的,不会让你的想法变得更糟。
              • 他们总是在主线程中实现的原因是因为开发人员可以根据自己的意愿分派到另一个队列中。如果 Parse 开发人员将其放入其他队列,则不是开发人员可以控制它。我认为这也不是他们的风格。
              • Finds objects asynchronously and calls the given block with the results. 他们没有在线程上说什么。但是,如果主线程不是很忙,iOS 也会将任务放回主线程。因此,您实际上没有必要分派回主线程。
              • stackoverflow.com/questions/21122842/… 这篇文章很有帮助。你可以考虑改变你的答案。虽然使用这种方式不会有什么坏处,但不是那么必要。
              猜你喜欢
              • 1970-01-01
              • 2015-09-13
              • 1970-01-01
              • 1970-01-01
              • 2018-06-07
              • 2023-02-24
              • 2015-08-10
              • 2020-12-31
              • 1970-01-01
              相关资源
              最近更新 更多