2015-04-20 4 views
2

Я имею дело с проблемой, с которой я не могу работать ... У меня есть таблица имен из массива клиентов DB, ​​каждый клиент имеет свойство имени среди других членов данных ,Удалить разделы UITable динамически с помощью commitEditingStyle в Swift

Я могу удалить строки в секции успешно, но то, что я не могу сделать, это удаление раздела (когда последняя строка в этом разделе удаляется, раздел должен исчезнуть).

я получил:

'NSInternalInconsistencyException', причина: «Invalid обновление: недопустимый количество секций. Количество разделов, содержащихся в таблице , просмотр после обновления (3) должен быть равен числу разделов , содержащихся в представлении таблицы перед обновлением (4), плюс или минус число вставленных или удаленных разделов (0 вставлено, 0 удалено).

Я знаю, что таблица выполняет некоторую проверку здравомыслия за кулисами данных, и это должно совпадать, но я не могу точно определить, когда, прежде чем вызывать deleteRowsAtIndexPaths? после? Когда я должен обновить свое свойство и/или словарь? Должен ли я управлять методом data-source numberOfSectionsInTableView?

Повторяю, для строк, удаляющих работу, таблица выходит из строки и обновляется должным образом. Последний ряд на секции - дело ...

Я думаю, что у меня что-то не хватает, вот почему я спрашиваю ... Не мог найти никакой помощи.

Спасибо вам большое!

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) { 
    if (editingStyle == UITableViewCellEditingStyle.Delete) { 
     // handle delete (by removing the data from the array and updating the tableview) 

     //Check if delete was press 
     if editingStyle == .Delete { 
      //Delete row from dataSource 
      if let tv = tableView 
      { 

       customerList.removeAtIndex(returnPositionForThisIndexPath(indexPath, insideThisTable: tableView)) 
       // Deletes the name of the customer from the customer list array, sorted by name 

       fillArrayOfNames() 
       //Fill the array of names for the sections-table, creating a dictionary with the name initials 
       //updated from the customer list array (below) 

       tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) //Crash in this line 

       tableView.reloadData() 

     } 
    } 
} 


func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return dictionaryOfPatientsInitials.count 
    } 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     var keysFromDictionary = dictionaryOfPatientsInitials.keys.array 

     keysFromDictionary.sort(<) 
     let keyByOrder = keysFromDictionary[section] 
     let arrayInThisSection = dictionaryOfPatientsInitials[keyByOrder] 

     return arrayInThisSection!.count 
    } 
+0

Является ли ваш источники данных изменяются? – Sirens

+0

@ Сиренс Да, это так. Это свойство var. И словарь, и массив. –

ответ

2

Вы почти там, но вы будете нуждаться способом обнаружения того, что раздел исчез, и который один пошел в какой момент вы можете позвонить deleteSections

кронштейн раздел Обновления в beginUpdate/endUpdate вызов, но не называйте reloadData (смотрите документацию для этих методов об этом)

/** 
remove customer from model layer 

:param: index index of customer to remove 

:returns: return section that was removed or nil if none was 
*/ 
func removeCustomer(index:Int)->Int? { 

    var removedSectionOrNil:Int? = nil 
    //logic to remove customer, rebuild model and detect if section has gone also 
    return removedSectionOrNil 

} 

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) { 
    if (editingStyle == UITableViewCellEditingStyle.Delete) { 
     // handle delete (by removing the data from the array and updating the tableview) 

     //Check if delete was press 
     if editingStyle == .Delete { 
      //Delete row from dataSource 
      if let tv = tableView 
      { 
       tv.beginUpdates() 

       let position = returnPositionForThisIndexPath(indexPath, insideThisTable: tableView) 
       let removedSection = removeCustomer(position) 

       tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) //Crash in this line 

       if let removedSection = removedSection { 
        tv.deleteSections(sections:NSIndexSet(index: removedSection) as IndexSet, withRowAnimation: .Automatic) 
       } 

       tv.endUpdates() 

      } 
     } 
} 

Не видя остальную часть вашего кода, это должен, но tableViews может быть сложным, когда исчезают разделы.

+0

Спасибо, ты сделал мое небо более ясным, единственное, что мне не хватает сейчас, это то, что я действительно не знаю, был ли раздел удален или нет. Я мог бы найти способ, заметив разницу в словарных клавишах, но в вашем методе метода мне тоже понадобится число ... правильно? –

+1

, который получил мужество функции 'removeCustomer'. Возможно, подсчитывайте клиентов за раздел до и после, а если count == 0, верните этот номер раздела. –

+0

Да, я что-нибудь придумаю, позвольте мне поработать над этим. Я вернусь, чтобы оценить ответ и опубликовать свое решение (если оно есть). Большое спасибо. –

0

Совместное мое решение до сих пор ... (пока не работает)

func removeCustomer(index:Int)->Int? { 

     var removedSectionOrNil:Int? = nil 

     let customerListOld = customerList 
     customerList.removeAtIndex(index) 

     let oldArray = CustomerToInitialsArray(customerListOld) 
     let newArray = CustomerToInitialsArray(customerList) 

     removedSectionOrNil = compareTwoArraysOfSortedKeys(oldArray, newArray: newArray) 

     fillArrayOfNames() 
     //Fill the array of names for the sections-table, creating a dictionary with the name initials 
     //updated from the customer list array (below) 

     //logic to remove customer, rebuild model and detect if section has gone also 
     return removedSectionOrNil 

    } 


func compareTwoArraysOfSortedKeys(oldArray: [String], newArray: [String]) -> Int? { 

     //oldArray should be bigger than new or equal 
     //if so, that means some value has been dropped out 

     if (oldArray.count > newArray.count) { 
      for index in 0..<newArray.count { 
       if (oldArray[index] != newArray[index]) { 
        return index 
       } 
      } 
      return newArray.count 
     } 
     return nil 
    } 

    func returnPositionForThisIndexPath(indexPath:NSIndexPath, insideThisTable theTable:UITableView)->Int{ 

     var i = 0 
     var rowCount = 0 

     while i < indexPath.section { 

      rowCount += theTable.numberOfRowsInSection(i) 

      i++ 
     } 

     rowCount += indexPath.row 

     return rowCount 
    } 
0

Я сижу с подобным вопросом - однако я подошел к проблеме с не-программирования способом. Что я сделал, это иметь два вида таблицы, которые просто перечисляют все ключи «Заказчик» на их данные. (Я использую ключ в словаре, который записывается в БД, а второй - список «клиентов» - каждый клиент является разделом. Затем я использовал контрольную метку в таблице ключей в качестве моего аксессуара для редактирования для ячейки в таблица Использования опции удаления для редактирования удалит ключ, а затем я тогда просто удалить этот элемент словаря в этом коде:..

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
     if editingStyle == UITableViewCellEditingStyle.Delete 
      actDict[keyArray[indexPath.row]] = nil 
      keyArray.removeAtIndex(indexPath.row) 
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) 
      try! writeFile!.addValuesToUserFile(actDict) 

     } 

    } 

Это работает безупречно для меня Извините за неполный первоначальный ответ