2016-08-31 5 views
1

Как и голова, я использую Firebase для хранения/удаления данных.Указатель Вне диапазона при удалении из TableView?

Вот мой viewDidLoad код:

override func viewDidLoad() 
{ 
    super.viewDidLoad() 

    observePeople() 

    tableView.delegate = self 
    tableView.dataSource = self 

} 

observePeople() метод работает, как это (я перезарядить таблицу дважды здесь)

func observePeople() 
{ 
    let ref = FIRDatabase.database().reference().child("Users") 
    ref.observeEventType(.ChildAdded, withBlock: 
    { (snapshot) in 

     if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname") 
     { 
      let fullname = "\(firstname) \(lastname)" 
      self.names.append(fullname) 

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

    }, withCancelBlock: nil) 

    ref.observeEventType(.ChildRemoved, withBlock: 
    { (snapshot) in 

    if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname"), dateOfBirth = snapshot.value?.objectForKey("Date of Birth"), zipcode = snapshot.value?.objectForKey("Zipcode") 
    { 
     print("We deleted the person \(firstname) \(lastname) with the details: \(dateOfBirth), \(zipcode)") 
     self.tableView.reloadData() 
    } 

    }, withCancelBlock: nil) 
} 

И в моем viewDidAppear я обновить таблицу снова:

override func viewDidAppear(animated: Bool) 
{ 
    tableView.reloadData() 
} 

Наконец, я один раз удаляю строку. Я получаю сообщение об ошибке, указывающее, что индекс отсутствует е. Интересно, когда я заполняю таблицу четырьмя элементами, если я удалю первый элемент, он будет ФАКТИЧЕСКИ удалять второй элемент, и если я удалю третий, он фактически удалит четвертый и т. Д. Я добавляю точки останова, чтобы наблюдать это явление как можно лучше, и он ломается сразу после того, как я удаляю его из таблицы.

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 
{ 
    if editingStyle == .Delete 
    { 
     let ref = FIRDatabase.database().reference().child("Users") 
     ref.observeEventType(.ChildAdded, withBlock: { (snapshot) in 

      if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname") 
      { 
       let fullname = "\(firstname) \(lastname)" 
       let currentName = self.names[indexPath.row] 

       if fullname == currentName 
       { 
        print("We have a match") 
        let currentKey = snapshot.key 
        ref.child(currentKey).removeValue() 

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

      } 

      }, withCancelBlock: nil) 
    } 

     names.removeAtIndex(indexPath.row) 
     tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
    } 
} 

Так сразу после метода tableView.deleteRows я получаю сообщение об ошибке. Это было какое-то время и, похоже, не может найти его. Кроме того, я всегда убеждаюсь, что массивы совпадают для базы данных и массива, поэтому они оба пустые одновременно, прежде чем я их заполню.

+0

Удалите этот код 'self.tableView.reloadData()' на вашей функции удаления. Потому что после самого удаления tableview update. Проверьте 'print (currentName)' даст представление. –

+0

ах, который бы не сработал, но я распечатаю его, чтобы отслеживать мое текущее имя –

ответ

2

Работу с firebase изменений, как вы обычно работаете с таблицами. Вы можете подумать, что вам нужно удалить из массива, а затем удалить строки из таблицыView, потому что это то, что мы делаем с данными массива в большинстве случаев, но при этом оно вызывает проблемы при запросе или прослушивании firebase. Лучший способ справиться с этим - не удалять любые данные из массивов или таблицы вручную в функции commitEditingStyle. Вместо этого удалите только значение из firebase. Затем в вашем слушателе для .ChildRemoved удалите объект из массива данных и перезагрузите таблицу.

Удалить

names.removeAtIndex(indexPath.row) 
    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 

И Вставьте удаление имени в .ChildRemoved слушателя

ref.observeEventType(.ChildRemoved, withBlock: 
{ (snapshot) in 

if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname"), dateOfBirth = snapshot.value?.objectForKey("Date of Birth"), zipcode = snapshot.value?.objectForKey("Zipcode") 
{ 
    print("We deleted the person \(firstname) \(lastname) with the details: \(dateOfBirth), \(zipcode)") 
    let fullname = "\(firstname) \(lastname)" 
    if let index = names.indexOf(fullname) { 
     names.removeAtIndex(index) 
     self.tableView.reloadData() 
    } 
} 

}, withCancelBlock: nil) 
+0

Ahhhh, что имеет смысл. Очень проницательный, большое спасибо! Это именно то, что мне нужно –

0

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

names.removeAtIndex(indexPath.row) 
    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
+0

Я пробовал это раньше, но это не сработало –