2014-10-02 2 views
1

Я пытаюсь вернуть разные ячейки в tableView. Обычно в этом случае я бы возвращал разные ячейки, а затем возвращал нуль внизу, но в этом случае он дает мне и ошибку. Я тоже пытался вернуть пустую ячейку, но также дает мне и ошибку.can not return cell in cellForRowAtIndexPath

Что я пытался

return nil 

и

var cell: UITableViewCell! 
    return cell 

но оба вернулись ошибки. Как я могу это исправить?

cellForRowAtIndex

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




    if indexPath.row == 0 { 


     let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as UITableViewCell 
     var imageFile = cell.viewWithTag(100) as PFImageView 
     imageFile.image = itemFile 


     cell.selectionStyle = UITableViewCellSelectionStyle.None 
     return cell 

    } else if indexPath.row == 1 { 
     let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("segmentCell", forIndexPath: indexPath) as UITableViewCell 

     var titleLabel = cell.viewWithTag(101) as UILabel? 
     titleLabel?.text = itemTitle 

     let segmentControl = cell.viewWithTag(102) as UISegmentedControl 
     segmentControl.selectedSegmentIndex = segment 
     segmentControl.setTitle("Beskrivelse", forSegmentAtIndex: 0) 
     segmentControl.setTitle("Sælger", forSegmentAtIndex: 1) 
     segmentControl.setTitle("Lokation", forSegmentAtIndex: 2) 
     segmentControl.tintColor = UIColor(rgba: "#619e00") 
     var font = UIFont(name: "Lato-Regular", size: 11) 
     var attributes:NSDictionary = NSDictionary(object: font , forKey: NSFontAttributeName) 
     segmentControl.setTitleTextAttributes(attributes, forState: UIControlState.Normal) 
     segmentControl.addTarget(self, action: "segmentAction:", forControlEvents: .ValueChanged) 


     cell.selectionStyle = UITableViewCellSelectionStyle.None 

     return cell 

    } else if indexPath.row == 2 { 
     switch segment { 
     case 0: 
      let cell = tableView.dequeueReusableCellWithIdentifier("CellZero", forIndexPath: indexPath) as DescViewCell 
      return cell 
     case 1: 
      let cell = tableView.dequeueReusableCellWithIdentifier("CellOne", forIndexPath: indexPath) as SellerViewCell 
      return cell 
     case 2: 
      let cell = tableView.dequeueReusableCellWithIdentifier("CellTwo", forIndexPath: indexPath) as LocationViewCell 
      return cell 
     default: 
      break 

     } 
    } 


    var cell: UITableViewCell! 
    return cell 
} 

ответ

1

Вы не должны возвращать нуль от cellForRowAtIndexPath. Вы всегда должны возвращать действительную ячейку.

var cell: UITableViewCell! 

Эта строка коды не создает какую-либо ячейки, это просто переменную UITableViewCell с нулевым содержанием, вы должны присвоить ему значение:

var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell 
return cell 
0

Вы только объявляя последний var cell: UITableViewCell! - вы не инициализация его. Вам нужно сделать что-то вроде

var cell = UITableViewCell(style: someStyle, reuseIdentifier: someID) 
return cell 
1

Вы должны объявить ячейку, прежде чем ваша логика if...then, а затем верните ее после. Вам не нужно инициализировать ячейку, если вы используете var:

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

    var cell: UITableViewCell! 

    if indexPath.row == 0 { 
     cell = tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as UITableViewCell 
     // ... 
    } else if indexPath.row == 1 { 
     cell = tableView.dequeueReusableCellWithIdentifier("segmentCell", forIndexPath: indexPath) as UITableViewCell 
     // ... 
    } else if indexPath.row == 2 { 
     // ... 
    } 

    return cell 
} 

(Просто убедитесь, что вы ловите все случаи - если ваше возвращение клеток без инициализации, вы получите сообщение об ошибке выполнения.)

5

Как указанная в previous answer for a similar question, -tableView:cellForRowAtIndexPath: должна вернуть UITableViewCell. Поэтому вы не можете вернуть nil. Тем не менее, я бы рекомендовал, чтобы избежать возвращения следующие коды в конце -tableView:cellForRowAtIndexPath: при использовании , если в другом месте или переключатель инструкции внутри него:

//bad code design 
var cell: UITableViewCell! 
return cell 

или:

//bad code design 
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell 
return cell 

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

Итак, каково было бы решение?

Главное, чтобы быть уверенным, что ваше последнее возможное значение для если еще утверждение установлено в else (не в else if). Точно так же главное, чтобы ваше последнее возможное значение для switch было установлено в default: (не в case XXX:).

Таким образом, ваш код должен выглядеть следующим образом:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    if indexPath.row == 0 { 
     let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("CellZero", forIndexPath: indexPath) as UITableViewCell 
     /* ... */ 
     return cell 
    } else if indexPath.row == 1 { 
     let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("CellOne", forIndexPath: indexPath) as CellOne 
     /* ... */ 
     return cell 
    } else { //set your last indexPath.row case in "else", not in "else if indexPath.row == 2"!!! 
     switch segment { 
     case 0: 
      let cell = tableView.dequeueReusableCellWithIdentifier("CellTwo", forIndexPath: indexPath) as CellTwo 
      /* ... */ 
      return cell 
     case 1: 
      let cell = tableView.dequeueReusableCellWithIdentifier("CellThree", forIndexPath: indexPath) as CellThree 
      /* ... */ 
      return cell 
     default: //set your last segment case in "default:", not in "case 2:"!!! 
      let cell = tableView.dequeueReusableCellWithIdentifier("CellFour", forIndexPath: indexPath) as CellFour 
      /* ... */ 
      return cell 
     } 
    } 
    //No need for a fictive "return cell" with this code!!! 
} 

Если segment не является обязательным, благодаря кортежей, вы можете даже уменьшить предыдущий код на этот:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    switch (indexPath.row, segment) { 
    case (0, _): 
     let cell = tableView.dequeueReusableCellWithIdentifier("CellZero", forIndexPath: indexPath) as UITableViewCell 
     /* ... */ 
     return cell 
    case (1, _): 
     let cell = tableView.dequeueReusableCellWithIdentifier("CellOne", forIndexPath: indexPath) as CellOne 
     /* ... */ 
     return cell 
    case (2, 0): 
     let cell = tableView.dequeueReusableCellWithIdentifier("CellTwo", forIndexPath: indexPath) as CellTwo 
     /* ... */ 
     return cell 
    case (2, 1): 
     let cell = tableView.dequeueReusableCellWithIdentifier("CellThree", forIndexPath: indexPath) as CellThree 
     /* ... */ 
     return cell 
    default: //case (2, 2) 
     let cell = tableView.dequeueReusableCellWithIdentifier("CellFour", forIndexPath: indexPath) as CellFour 
     /* ... */ 
     return cell 
    } 
} 
+0

'default: // case (2, 2)' бит чувствует себя неэлегантным. Возможно, используйте «провал»? Но мне это даже не очень нравится. – pkamb