2016-08-06 4 views
0

Я пытаюсь спроектировать View, где я могу показать элементы в синхронизации с моей базой данных Firebase. Каждый раз, когда элемент в моем массиве изменяется, он дублируется. Пытался использоватьНе удается перезагрузить UITableView

self.tableView.reloadData() 

но ничего не меняется. Пробовал также

self.tableView.beginUpdates() 
self.tableView.reloadRowsAtIndexPaths(NSArray.init(object: indexPath) as! [NSIndexPath], withRowAnimation: .Automatic) 
self.tableView.endUpdates() 

и он не работал, как ранее. я пытался безуспешно выполнять перегрузочные Tableview в основном потоке с использованием функции

performSelectorOnMainThread 

Я отправляю мой код для вас, ребята, так что кто-то может мне помочь. Im совершенно новый для программирования iOS, и я не могу понять, когда перезагружать данные в tableView. Даже после чтения документации Apple.

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

    let alert = UIAlertController(title: "Akcja", message: "Wybierz akcję", preferredStyle: .ActionSheet) 

    let changeFieldNumberAction = UIAlertAction(title: "Zmień numer boiska", style: .Default, handler: {(action) in 

     self.showAlertOfChangingFieldNumber(indexPath) 

    }) 

    let sendToRefereeAction = UIAlertAction(title: "Wskaż sędziego", style: .Default, handler: {(action) in 
     //self.championshitTournamentMode = false 

    }) 

    let cancelAction = UIAlertAction(title: "Anuluj", style: .Cancel, handler: nil) 

    alert.addAction(cancelAction) 
    alert.addAction(changeFieldNumberAction) 
    alert.addAction(sendToRefereeAction) 

    self.presentViewController(alert, animated: true, completion: nil) 
} 

func showAlertOfChangingFieldNumber(indexPath: NSIndexPath) { 

    let fieldNumberAlert = UIAlertController(title: "Numer boiska", message: "Wpisz numer boiska", preferredStyle: .Alert) 

    fieldNumberAlert.addTextFieldWithConfigurationHandler({(textField: UITextField!) -> Void in 
     textField.placeholder = "Numer boiska" 
     textField.keyboardType = UIKeyboardType.NumberPad 
    }) 

    let saveAction = UIAlertAction(title: "Zapisz", style: .Default, handler: {(action) -> Void in 

     let fieldNumberTextField = fieldNumberAlert.textFields![0] as UITextField 
     let fieldNumber = Int(fieldNumberTextField.text!) 
     self.updateGameFieldNumber(fieldNumber!, indexPath: indexPath) 
    }) 

    let cancelAction = UIAlertAction(title: "Anuluj", style: .Cancel, handler: nil) 

    fieldNumberAlert.addAction(cancelAction) 
    fieldNumberAlert.addAction(saveAction) 

    self.presentViewController(fieldNumberAlert, animated: true, completion: nil) 

} 

func updateGameFieldNumber(fieldNumber: Int, indexPath: NSIndexPath){ 

    let gameKey = games[indexPath.row].key 
    let ref = FIRDatabase.database().reference().child("games").child(gameKey) 

    games[indexPath.row].fieldNumber = fieldNumber 
    ref.updateChildValues(games[indexPath.row].toAnyObject() as! [NSObject : AnyObject]) 
    //self.games.removeAtIndex(indexPath.row+1) 
    self.tableView.beginUpdates() 
    self.tableView.reloadRowsAtIndexPaths(NSArray.init(object: indexPath) as! [NSIndexPath], withRowAnimation: .Automatic) 
    self.tableView.endUpdates() 
} 

И мои функции делегата Tableview и функция сделана для заполнения мой массив на основе базы данных Firebase выглядит так:

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

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! GameViewCellTableViewCell 

    if games[indexPath.row].fieldNumber == 0 { 
     cell.fieldNumberLabel.text = "-" 
    } else { 
     cell.fieldNumberLabel.text = String(games[indexPath.row].fieldNumber) 
    } 
    cell.firstParticipantLabel.text = games[indexPath.row].firstParticipant 

    cell.secondParticipantLabel.text = games[indexPath.row].secondParticipant 

    cell.gameImage.image = UIImage(named: "tenisBall") 

    if games[indexPath.row].completed != true { 
     cell.backgroundColor = UIColor.init(red: 1, green: 109.0/255, blue: 95.0/255, alpha: 1) 
    } else { 
     cell.backgroundColor = UIColor.init(red: 160/255, green: 1, blue: 86/255, alpha: 1) 
    } 

    return cell 

} 

override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return 1 
} 

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

func getGames() { 

    let ref = FIRDatabase.database().reference().child("games") 

    ref.observeEventType(.Value, withBlock: {snapshot in 

     for item in snapshot.children { 

      let gameItem = GameItem(snapshot: item as! FIRDataSnapshot) 
      if(gameItem.tournamentName == self.tournamentName) { 
       self.games.append(gameItem) 
      } 

     } 
     self.tableView.reloadData() 
    }) 

} 
+0

Это простой сценарий. Для начала вам просто нужно вызвать self.tableView.reloadData(). Если это не работает, у вас есть более фундаментальная проблема, которая не будет решена с помощью .reloadRowsAtIndexPath или выполненияSelectorOnMainThread. –

+0

Как выглядят ваши функции cellForRowAtIndexPath, numnerOfSections и numberOfRowsInSection? –

+0

@MikeTaverne Я редактировал свой пост, чтобы вы могли видеть, что происходит внутри функций делегата tableView. – michalbanan

ответ

0

Он получает дублируется, потому что вместо того, чтобы обновить значение в вашей «игры» массив, вы добавляете измененное значение в массив. Это происходит в методе getgames().

+0

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

+0

Возможно, это более эффективно, если вы проверяете, присутствует ли игра в массиве в вашем блоке наблюдения. Если это так, обновите его, если не добавьте. Таким образом, в первый раз каждая игра будет добавлена, и когда блок автоматически вызывается для обновления, он не добавляет никаких данных, которые вам придется удалить после этого. – emiledecosterd

+0

Спасибо! Я использовал свойство 'contains' массива, чтобы проверить, присутствует ли игра. Это решило мою проблему. – michalbanan

0

внутри

func getGames() 

после

self.games.append(gameItem) 
dispatch_async(dispatch_get_main_queue(), { 
self.tableView.reloadData() 
})