2016-01-15 2 views
0

Все мои ячейки имеют переключатель, который перемещает ячейку в нижней части таблицы. Он работает нормально, однако, когда достаточно клеток, чтобы опуститься ниже видимых границ, я получаю сообщение об ошибке, что ячейка не существует. Это не работает, потому что мне нужно обновить ВСЕ ячейки sender.tag.Доступ к ячейкам, которые не видны в UITableView

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

     let cell: TaskTableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as! TaskTableViewCell 

     var task = tasks[indexPath.row] 

     let index = tasks.indexOf(task)! 

     cell.cellSwitch.tag = index 
     cell.addSubview(cell.cellSwitch) 
     cell.tag = index 
     cell.cellSwitch.addTarget(self, action: "switched:", forControlEvents: UIControlEvents.TouchUpInside) 

    return cell 
} 

func switched(sender: UIButton) { 
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0) 
let finalIndexPath = NSIndexPath(forRow: tasks.count - 1, inSection: 0) 

let task = tasks[indexPath.row] 
tasks.removeAtIndex(indexPath.row) 
tasks.append(task) 
self.taskTableView.moveRowAtIndexPath(indexPath, toIndexPath: finalIndexPath) 

for var i = 0; i < tasks.count; i ++ { 

let cellIndex = NSIndexPath(forRow: i, inSection: 0) 
let cell: TaskTableViewCell = self.taskTableView.cellForRowAtIndexPath(cellIndex) as! TaskTableViewCell 
cell.cellSwitch.tag = cellIndex.row 

} 

} 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    var cellToBeReturned = UITableViewCell() 

    if indexPath.row != tableView.numberOfRowsInSection(0) - 1 { 
     let cell: TaskTableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as! TaskTableViewCell 

     var task = tasks[indexPath.row] 

     cell.cellFlatSwitch.removeFromSuperview() 
     cell.currentStreak.removeFromSuperview() 

     switch(task.icon) { 

     case "heart"?: 
      task.color = colors[0] 
     case "meditate"?: 
      task.color = colors[1] 
     case "leaf"?: 
      task.color = colors[2] 
     case "run"?: 
      task.color = colors[3] 
     case "muscle"?: 
      task.color = colors[4] 
     default: 
      task.color = .blackColor() 
     } 

     switch(task.icon) { 
     case "heart"?: 
      cell.pretickButton.setImage(Icons.imageOfHeartIcon, forState: .Normal) 
     case "meditate"?: 
      cell.pretickButton.setImage(Icons.imageOfMeditationIcon, forState: .Normal) 
     case "run"?: 
      cell.pretickButton.setImage(Icons.imageOfRunIcon, forState: .Normal) 
     case "leaf"?: 
      cell.pretickButton.setImage(Icons.imageOfLeafIcon, forState: .Normal) 
     case "muscle"?: 
      cell.pretickButton.setImage(Icons.imageOfMuscleIcon, forState: .Normal) 
     default: 
      cell.pretickButton.setImage(Icons.imageOfLeafIcon, forState: .Normal) 
     } 

     if task.longestStreak >= 21 { 

      cell.starImage.alpha = 1 

     } else { 
      cell.starImage.alpha = 0 

     } 

     if localSettings.habitPreview == "dayCounter" { 

      cell.currentStreak = LTMorphingLabel(frame: CGRectMake(11, 29, 39, 31)) 
      cell.currentStreak.morphingEffect = LTMorphingEffect.Anvil 
      cell.currentStreak.textAlignment = NSTextAlignment.Center 
      cell.currentStreak.text = String(task.consecutiveDays!) 
      cell.addSubview(cell.currentStreak) 
      cell.streakSublabel.textAlignment = .Center 
      cell.currentStreak.adjustsFontSizeToFitWidth = true 
      cell.streakSublabel.adjustsFontSizeToFitWidth = true 
      cell.growthPreviewImage.hidden = true 
      cell.streakSublabel.hidden = false 

     } else { 

      if task.growth > 0 && task.growth <= 21 { 
       cell.growthPreviewImage.image = UIImage(named: "growth\(task.growth!)") 
      } else if task.growth <= 0 { 
       cell.growthPreviewImage.image = UIImage(named: "growth1") 
      } else if task.growth > 21 { 
       cell.growthPreviewImage.image = UIImage(named: "growht21") 
      } 

      cell.growthPreviewImage.hidden = false 
      cell.streakSublabel.hidden = true 

     } 

     if task.consecutiveDays == 1 { 
      cell.streakSublabel.text = "day" 
     } else { 
      cell.streakSublabel.text = "days" 
     } 

     cell.taskLabel.adjustsFontSizeToFitWidth = true 
     cell.taskLabel.text = task.name 
     cell.taskLabel.textColor = task.color 
     cell.cellFlatSwitch = AIFlatSwitch(frame: CGRectMake(300, 15, 70, 70)) 
     cell.cellFlatSwitch.lineWidth = 2.3 
     cell.cellFlatSwitch.strokeColor = task.color! 
     cell.cellFlatSwitch.trailStrokeColor = task.color! 

     let index = tasks.indexOf(task)! 

     cell.pretickButton.tag = index 
     cell.backgroundColor = UIColor.clearColor() 
     cell.addSubview(cell.cellFlatSwitch) 
     cell.tag = index 

     cell.bringSubviewToFront(cell.pretickButton) 
     cell.pretickButton.addTarget(self, action: "switched:", forControlEvents: UIControlEvents.TouchUpInside) 
     cell.sendSubviewToBack(cell.cellFlatSwitch) 

     if task.doneToday == true { 
      cell.cellFlatSwitch.selected = true 
      cell.pretickButton.alpha = 0.0101 
     } else { 
      cell.cellFlatSwitch.setSelected(false, animated: false) 
      cell.pretickButton.alpha = 1.0 
     } 

     cellToBeReturned = cell 

    } else { 

     let cell: AddNewTableViewCell = tableView.dequeueReusableCellWithIdentifier("add") as! AddNewTableViewCell 
     cell.tag = indexPath.row 

     cellToBeReturned = cell 
    } 

    return cellToBeReturned 
} 

Любые советы или помощь с благодарностью.

+5

Поскольку ячейки повторно используются, вы не можете назначать метки для ячеек, которые просто не существуют. –

+2

Вы назначаете теги на 'cellForRowAtIndexPath'? –

+2

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

ответ

2

Вы делаете это неправильно.

Не вызывайте методы с объектами NSIndexPath, чтобы перемещать ячейки вокруг. Реализация UITableView предлагает вам следует использовать один источник данных (может быть массив, словарь, обычай NSObject, NSFetchedResultsController и т.д.), чтобы выполнить всю соответствующую UITableViewDataSource и UITableViewDelegate методы делегата и вы делаете обновление источника первых данных, то звоните либо reloadData, либо beginUpdates и endUpdates на свой UITableView всякий раз, когда вам нужно освежить ваше мнение.

В вашем случае я бы просто использовал 2 NSMutableArray, один для предметов с, один для без тегов. Ваш обработчик переключения должен извлекать элемент из указателя ячейки и перемещать его из одного массива в другой. Затем вы можете позвонить beginUpdates и переместить свою ячейку соответствующим образом.

Они предназначены для внесения изменений в источник данных в первую очередь и в соответствии с вашими методами UITableViewDataSource, особенно методом cellForAtIndexPath. В основном ошибка, которую вы получаете, скорее всего, потому что ваш источник данных не синхронизирован с видимыми ячейками.

Надеюсь, это поможет.

+0

Хорошо, большое вам спасибо за это. Но как я узнаю, какой индекс перемещается внутри массива без 'indexPath.row'? – exotue

+0

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

+0

Это также зависит от того, как вы реализуете метод обработчика переключателя. одним из способов является вызов родительского представления вашего 'UISwitch' для получения' UITableViewCell', а затем вы вызываете 'UITableView.indexPathForCell:', чтобы получить индекс для вашего источника данных. дайте мне знать, если это не имеет смысла для u. – believesInSanta

Смежные вопросы