cant return cell in cellForRowAtIndexPath

后端 未结 4 1675
北荒
北荒 2021-01-15 15:44

i\'m trying to return different cells in a tableView. Normally in this case i would return different cells and then return nil at the bottom, but in this case it gives me an

相关标签:
4条回答
  • 2021-01-15 15:44

    As indicated in a previous answer for a similar question, -tableView:cellForRowAtIndexPath: must return a UITableViewCell. So you can't return nil. However, I would also recommend to avoid returning the following codes at the end of -tableView:cellForRowAtIndexPath: when you use if else or switch statements inside it:

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

    or:

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

    You can do better code than creating an UITableViewCell instance that is never called just in order to silent Xcode warnings!

    So what would be the solution?

    The key thing is to be sure that your last possible value for an if else statement is set in else (not in else if). In the same way, the key thing is to be sure that your last possible value for a switch statement is set in default: (not in case XXX:).

    Thus, your code should look like this:

    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!!!
    }
    

    If segment is not an optional, thanks to tuples, you can even reduce the previous code to this:

    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 讨论(0)
  • 2021-01-15 15:52

    You mustn't return nil from cellForRowAtIndexPath. You always should return a valid cell.

     var cell: UITableViewCell!
    

    This line of code doesn't create any cell, it just a UITableViewCell variable with nil content, you have to assign a value to it:

    var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    return cell
    
    0 讨论(0)
  • 2021-01-15 15:52

    You are only declaring the last var cell: UITableViewCell! - you are not initialising it. You need to do something like

    var cell = UITableViewCell(style: someStyle, reuseIdentifier: someID)
    return cell
    
    0 讨论(0)
  • 2021-01-15 15:54

    You need to declare the cell before your if...then logic, then return it after. You don't have to initialize the cell if you use 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
    }
    

    (Just make sure you catch all cases - if your return cell without initializing you'll get a runtime error.)

    0 讨论(0)
提交回复
热议问题