Peter Warbo
Peter Warbo

Reputation: 11728

iOS - UITableViewCell subclass with two different images

I'm subclassing UITableViewCell to have one image on the far left, then some text in the middle and then some text on the far right.

This UITableViewCell subclass will only have two images depending on a condition. What I've done before when I have used images in UITableViewCell subclass I have declared them as

static UIImage *image = nil; 

and then in the +(void)initialize method I have assigned them. This is made only to have a class instances of the images and not using up resources to assign these images to every instance of UITableViewCell.

So my question is now, depending on a condition in my UIViewController that is calling the cellForRowAtIndexPath method I should show a UITableViewCell with imageA or imageB. So in pseudo-code it would look something like this

if (conditionA) { 
    // Set image of cell to be imageA 
} else { 
    // Set image of cell to be imageB 
}

So how do I achieve this with a subclassed UITableViewCell? I was thinking of one way would be to observe a property in the UITableViewCell and when that property would change I would set the cell image accordingly but that seems to be a little bloated for something that should be pretty easy?

The ideal way would be to set it in the init method of the UITableViewCell but then I would not be able to reuse the cells right?

Upvotes: 0

Views: 442

Answers (3)

Anurag
Anurag

Reputation: 141909

You shouldn't worry about redundant images being created for each instance. The UIImage class already has an inbuilt cache, and it does not create a new image instances as long as you are creating them using the imageNamed: selector.

From the docs for the imageNamed: method in UIImage,

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method loads the image data from the specified file, caches it, and then returns the resulting object.

If the two images are predefined and won't change, then you can simplify the subclasses cell's interface. Only allow the users of this subclass to tell it which type of image should be used. You could use an enum for that.

In the UITableViewCell's subclass header, create the enum. Use whatever names suits your use-case.

typedef enum {
  ImageTypeOne,
  ImageTypeTwo
} ImageType;

@property (nonatomic) ImageType imageType;

Inside the implementation, override the generated setter as:

- (void)setImageType:(ImageType)newImageType {
    imageType = newImageType;

    if (imageType == ImageTypeOne) {
        theImageView.image = [UIImage imageNamed:@"one"];
    } 
    else if (imageType == ImageTypeOne) {
        theImageView.image = [UIImage imageNamed:@"two"];
    }
    // this will resize the image view to fit the image.
    [theImageView sizeToFit];
}

Inside your cellForRowAtIndexPath: method, simply set this property depending on the condition.

if (conditionA) { 
    myCustomCell.imageType = ImageTypeOne;
} else { 
    myCustomCell.imageType = ImageTypeTwo;
}

Upvotes: 1

Paul.s
Paul.s

Reputation: 38728

I don't get the use of the static UIImage. The view should not own it's data.

If this was me I would have a property for each UIImage in the dataSource that was only instantiated once and then I would just configure the cells normally by having the dataSource tell them what to display.

It seems like your making more work for yourself and introducing a very rigid structure

Upvotes: 0

A-Live
A-Live

Reputation: 8944

The ideal way would be to set it in the init method of the UITableViewCell but then I would not be able to reuse the cells right?

That's correct, but there's solution not too far away. Use the same technique with two static images and update the imageView's image with a special method like updateMyCellImage depending on the key property value.

The second step is to prepare such a setter for that key property, that would call this method after the value of the key property is changed.

Then you'll only need to set the key property value at cellForRowAtIndexPath after the cell is dequeued/initialized and the imageView's image will be updated for you, you'll be able to reuse the cells.

Upvotes: 0

Related Questions