swift上的频繁更新表视图失败

时间:2015-08-11 11:19:17

标签: ios swift uitableview

我有一个tableview需要更新第二。代码如下。我设计了headerview以具有下拉功能,当标题点击时显示其余部分。当我试图点击标题时,代码将崩溃,线程停止,xcode没有提供任何关于如何和为什么的提示。

func didListOfBLEDevicesUpdate(newDevice: BLEDevice)
{
  println("receivedDevice from scanner every second: \(newDevice.deviceName)")
    self.deviceTableView.reloadData()
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return BLEDevice.listOfDevices.items.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1;
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return BLEDevice.listOfDevices.items[section].deviceName
}

func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return 1
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if(IsExpandedMode[indexPath.section] == true){
        return 400
    }
    return 70;
}

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40))
    headerView.backgroundColor = UIColor.grayColor()
    headerView.tag = section

    let headerString = UILabel(frame: CGRect(x: 10, y: 10, width: tableView.frame.size.width-10, height: 30)) as UILabel
    headerString.text = BLEDevice.listOfDevices.items[section].deviceName
    headerView .addSubview(headerString)
    let headerTapped = UITapGestureRecognizer (target: self, action:"sectionHeaderTapped:")
    headerView .addGestureRecognizer(headerTapped)
    return headerView
}

func sectionHeaderTapped(recognizer: UITapGestureRecognizer) {
    println("Tapping working")
    println(recognizer.view?.tag)


    var indexPath : NSIndexPath = NSIndexPath(forRow: 0, inSection:(recognizer.view?.tag as Int!)!)
    if (indexPath.row == 0) {

        var collapsed = self.IsExpandedMode [indexPath.section]
        collapsed = !collapsed;

        self.IsExpandedMode[indexPath.section] = collapsed
        //reload specific section animated
        var range = NSMakeRange(indexPath.section, 1)
        var sectionToReload = NSIndexSet(indexesInRange: range)
        self.deviceTableView.reloadSections(sectionToReload, withRowAnimation:UITableViewRowAnimation.Fade)
    }
 }

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell : DeviceTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! DeviceTableViewCell

      let row = indexPath.row
    cell.deviceName!.text = BLEDevice.listOfDevices.items[row].deviceName
    cell.connectionStatus.text = BLEDevice.listOfDevices.items[row].connectionStatus
    cell.deviceSignalStrengthen.text = BLEDevice.listOfDevices.items[row].RSSI
    cell.manufacturerData.text = BLEDevice.listOfDevices.items[row].advertisementPackage.cBAdvertisementDataManufacturerData
    cell.serviceUUID.text = BLEDevice.listOfDevices.items[row].advertisementPackage.cBAdvertisementDataServiceUUIDs
    cell.serviceData.text = DataConvertHelper.getNSDictionary(BLEDevice.listOfDevices.items[row].advertisementPackage.cBAdvertisementDataServiceData)
    cell.TxPowerLevel.text = BLEDevice.listOfDevices.items[row].advertisementPackage.cBAdvertisementDataTxPowerLevel
    cell.IsConnectable.text = DataConvertHelper.getBool(BLEDevice.listOfDevices.items[row].advertisementPackage.cBAdvertisementDataIsConnectable)
    cell.solicitedServiceUUID.text = BLEDevice.listOfDevices.items[row].advertisementPackage.cBAdvertisementDataSolicitedServiceUUIDs
    cell.shortenedLocalName.text = BLEDevice.listOfDevices.items[row].advertisementPackage.cBAdvertisementDataLocalName
      return cell
}

2 个答案:

答案 0 :(得分:0)

使用重新加载部分并重新加载行而不是重新加载数据

答案 1 :(得分:0)

您用来处理表的方法似乎相当复杂。另一种选择如下:

1)您的代码假设是每个设备都与一个部分相关联。如评论中所述,您的cellForRorAtIndexPath方法似乎使用[row]索引数据模型,但模型基于[section],因为您总是将行数返回为1每个部分和部分的数量是设备的数量。

2)不是为每个部分使用标题视图而必须添加手势识别器,只需创建一个自定义单元格来表示设备并将该行设为0。

3)因此每个设备都与一个部分相关联,每个部分的第0行是标题信息单元,而不是标题视图。使标题视图为零。您可以使用标题高度在各个部分之间留一个空隙。

4)添加代码以检测细胞的选择。当单元格行为0时,它的标题单元格。如果设备已折叠,请将其设置为展开,反之亦然,然后重新加载该部分。

5)为您提供新的自定义单元格下拉信息。这将是显示信息的任何部分的第1行。

6)更新部分中的行数,如果展开则返回2,如果折叠,则返回1。

7)更新cellForRowAtIndexPath以返回第0行的标题单元格和第1行的详细信息单元格。确保将[row]索引修复为[section]索引。

这为您提供了一个设备标题单元格表,单击该图表时会在下方插入一个详细信息单元格,再次单击时将其删除,不需要手势识别器。

您需要确保数据模型更新正常运行。从错误中可以看出,您没有正确更新数据模型:特别是删除设备。