TableView reloadData() 未显示所有数据,即使包含值的数组已填充 (swift)

TableView reloadData() not showing all data, even though the array with values is filled (swift)

我有一个 table视图,其中填充了 http 调用的结果。数据被传递到名为 tripTimes 的数组中。 triptimes 包含特定日期内某些行程的相关信息。当天每次旅行的开始时间都传递到 self.tableData 并插入到 table 视图中。

在此之后,我重新加载 table 和...奇怪的结果。

数组 tableData 被正确填充,但在我调用 self.tableView.reloadData() 之后几乎所有单元格都被正确填充。但是,第一个单元格留空直到我点击它或者如果我等待大约 5 秒并且最后一个单元格也是空的,但它在同一时间后获得与第一个单元格相同的值。

我认为它与 dispatch_async 部分有关,但我对 swift 和 iOS 还很陌生,所以我不知道去哪里找。当我在 dispatch_async 函数中打印 self.tableData 的内容时,数组包含正确的值。

下面是我的 viewController

的代码
import UIKit
import Foundation
import SwiftHTTP
class TripSelect: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var dateTextField: UITextField!
    @IBOutlet weak var tableView: UITableView!

    @IBAction func showTrips(sender: AnyObject) {

        //if data is already present in tableData, empty it first
        if self.tripTimes.count != 0 && self.tableData.count != 0 {
            for var i=0; i<self.tripTimes.count; i++ {
                self.tableData.removeObjectAtIndex(0)
                let indexPathToRemove = NSIndexPath(forRow: 0, inSection: 0)
                self.tableView.deleteRowsAtIndexPaths([indexPathToRemove], withRowAnimation: .Automatic)
            }
            dispatch_async(dispatch_get_main_queue(), {
                self.tableView.reloadData()
            })
        }
        var request = HTTPTask()
        request.GET("<MY_URL>", parameters: ["date": dateTextField.text], success: {(response: HTTPResponse) in
            if let data = response.responseObject as? NSData {

                let str = NSString(data: data, encoding: NSUTF8StringEncoding) as String
                let str2 = "\"not enough data for this day\""

                if str != str2 {
                    let json:AnyObject = JSON.parse(str)

                    self.dayLatLongs = json["dayLatLongs"] as Array
                    self.tripTimes = json["tripTimes"] as Array

                    var tripLatLongs:[AnyObject] = self.dayLatLongs[0] as Array
                    var firstTrip:[AnyObject] = tripLatLongs[0] as Array
                    var tripStartTime:String = ""
                    for var i=0; i<self.tripTimes.count; i++ {
                        tripStartTime = self.tripTimes[i]["startTime"] as String
                        //println("\(tripStartTime)")
                        self.tableData.addObject(tripStartTime)
                        let indexPath = NSIndexPath(forRow: 0, inSection: 0)
                        self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
                    }
                    dispatch_async(dispatch_get_main_queue(), {
                        println(self.tableData)
                        self.tableView.reloadData()
                    })
                } else {println(str)}
            }
            },failure: {(error: NSError, response: HTTPResponse?) in
                println("error: \(error)")
        })
    }

    var dayLatLongs:[AnyObject] = []
    var tripTimes:[AnyObject] = []
    var tableData: NSMutableArray! = NSMutableArray()

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.tableData.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
        cell.textLabel?.text = self.tableData.objectAtIndex(indexPath.row) as? String
        return cell
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        var backgroundView = UIView(frame: CGRectZero)
        self.tableView.tableFooterView = backgroundView
        self.tableView.backgroundColor = UIColor.clearColor()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

更新:

var indexPaths:[NSIndexPath] = [NSIndexPath]()
for var i=0; i<self.tripTimes.count; i++ {
    tripStartTime = self.tripTimes[i]["startTime"] as String
    self.tableData.addObject(tripStartTime)
    indexPaths.append(NSIndexPath(forRow: i, inSection: 0))
}
self.tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)

现在结果显示正确,但仅在我 'drag' 几次 table 之后。

您的问题出在第一个 if 子句中:

 if self.tripTimes.count != 0 && self.tableData.count != 0 {
            for var i=0; i<self.tripTimes.count; i++ {
                self.tableData.removeObjectAtIndex(0)
                let indexPathToRemove = NSIndexPath(forRow: 0, inSection: 0)
                self.tableView.deleteRowsAtIndexPaths([indexPathToRemove], withRowAnimation: .Automatic)
            }
            dispatch_async(dispatch_get_main_queue(), {
                self.tableView.reloadData()
            })
        }

您总是只删除索引 0 处的值,而不使用 i。因此,将所有硬编码 0 替换为您的索引 i:

 if self.tripTimes.count != 0 && self.tableData.count != 0 {
            for var i=0; i<self.tripTimes.count; i++ {
                self.tableData.removeObjectAtIndex(i)
                let indexPathToRemove = NSIndexPath(forRow: i, inSection: 0)
                self.tableView.deleteRowsAtIndexPaths([indexPathToRemove], withRowAnimation: .Automatic)
            }
            dispatch_async(dispatch_get_main_queue(), {
                self.tableView.reloadData()
            })
        }

此答案的所有功劳都归功于@A-Live。

更新了建议的更改:

为了删除单元格,我将函数更改为

dispatch_async(dispatch_get_main_queue(), {
    if self.tripTimes.count != 0 && self.tableData.count != 0 {
        self.tableData = []
        self.tableView.deleteRowsAtIndexPaths(self.indexPaths, withRowAnimation: .Automatic)
        self.indexPaths = []
    }
})

要添加单元格,我将函数更改为

dispatch_async(dispatch_get_main_queue(), {
    for var i=0; i<self.tripTimes.count; i++ {
        tripStartTime = self.tripTimes[i]["startTime"] as String
        self.tableData.addObject(tripStartTime)
        self.indexPaths.append(NSIndexPath(forRow: i, inSection: 0))
    }
    self.tableView.insertRowsAtIndexPaths(self.indexPaths, withRowAnimation: .Automatic)
})