yesthisisjoe
yesthisisjoe

Reputation: 2035

Better way to initialize different cell types inside an if statement

In my code, a cell will be of one type if it is in the first tableView section, and another if it is not.

var cell = UITableViewCell()

if indexPath.section == 0 {
    cell = tableView.dequeueReusableCellWithIdentifier("UpcomingWorkoutCell", forIndexPath: indexPath) as! MyWorkoutsTableViewCell
    cell.nameLabel.text = workout.trainer.name
    cell.dateLabel.text = workout.getDateString()
    cell.timeLabel.text = workout.getTimeString()
    cell.trainerImage.image = workout.image
} else {
    cell = tableView.dequeueReusableCellWithIdentifier("PastWorkoutCell", forIndexPath: indexPath) as! PastWorkoutTableViewCell
    cell.nameLabel.text = workout.trainer.name
    cell.dateLabel.text = workout.getDateString()
    cell.timeLabel.text = workout.getTimeString()
    cell.trainerImage.image = workout.image
    cell.ratingControl.rating = workout.rating // Exclusive to PastWorkoutCell
}

Is there a better way to write this? Can I somehow get rid of the initial declaration as a UITableViewCell and shorten my code by a line?

Also, MyWorkoutsTableViewCell and PastWorkoutCell have almost all their properties in common. Can I avoid repeating code in each of the branches of the if statement to set all of them? Right now cell is a UITableViewCell that doesn't have any properties so I can't seem to do it outside the two branches.

Upvotes: 0

Views: 66

Answers (4)

Nirav D
Nirav D

Reputation: 72410

Have you try this

var cell = tableView.dequeueReusableCellWithIdentifier("UpcomingWorkoutCell", forIndexPath: indexPath) as! MyWorkoutsTableViewCell
if indexPath.section != 0 {
    cell = tableView.dequeueReusableCellWithIdentifier("PastWorkoutCell", forIndexPath: indexPath) as! PastWorkoutTableViewCell
    cell.ratingControl.rating = workout.rating
}
cell.nameLabel.text = workout.trainer.name
cell.dateLabel.text = workout.getDateString()
cell.timeLabel.text = workout.getTimeString()
cell.trainerImage.image = workout.image

Upvotes: 5

Developer Sheldon
Developer Sheldon

Reputation: 2160

Nirav's answer is good except for a bit changes

var cell = tableView.dequeueReusableCellWithIdentifier("UpcomingWorkoutCell", forIndexPath: indexPath) as! MyWorkoutsTableViewCell if indexPath.section != 0 { cell = tableView.dequeueReusableCellWithIdentifier("PastWorkoutCell", forIndexPath: indexPath) as! PastWorkoutTableViewCell cell.ratingControl.rating = workout.rating }

cell.nameLabel.text = workout.trainer.name cell.dateLabel.text = workout.getDateString() cell.timeLabel.text = workout.getTimeString()

Upvotes: 0

matt
matt

Reputation: 534950

The only thing that's unpleasant about your code is that the cell declared in the first line is immediately replaced by the real cell. To avoid that, use a define-and-call function:

let cell : UITableViewCell = {
    if indexPath.section == 0 {
        let cell = // ...
        return cell
    }
    else {
        let cell = // ...
        return cell
    }
}()

The duplication can be avoided through a common (abstract) superclass.

class MyCell : UITableViewCell {
    // declare nameLabel, dateLabel, timeLabel etc.
}
class MyWorkoutsTableViewCell: MyCell {}
class PastWorkoutCell: MyCell {}

Now we can restructure like this:

let cell : MyCell = {
    if indexPath.section == 0 {
        let cell = // ...
        return cell
    }
    else {
        let cell = // ...
        return cell
    }
}()
// configure MyCell once, here, and return it

Upvotes: 1

MirMiratom
MirMiratom

Reputation: 76

var cell = UITableViewCell()

    if indexPath.section == 0 {
        cell = tableView.dequeueReusableCellWithIdentifier("UpcomingWorkoutCell", forIndexPath: indexPath) as! MyWorkoutsTableViewCell

    } else {
        cell = tableView.dequeueReusableCellWithIdentifier("PastWorkoutCell", forIndexPath: indexPath) as! PastWorkoutTableViewCell

    }
    cell.nameLabel.text = workout.trainer.name
    cell.dateLabel.text = workout.getDateString()
    cell.timeLabel.text = workout.getTimeString()
    cell.trainerImage.image = workout.image

Upvotes: 0

Related Questions