How to set background gradient of UITableViewCell?

I would like to create a UITableViewCell gradient background, for example, the default Clock Clock application that comes on the iPhone. I'm not quite sure how to do this. Create an image and install it:

cell.contentView.backgroundColor = [UIColor alloc] initWithPatternImage:[UIImage imageNamed:@"background.png"]]; 

or is there a different / better approach?

+7
objective-c iphone cocoa-touch uitableview
source share
2 answers
+7
source share

I found an existing answer to this question, but was not satisfied. Here, an alternative approach requiring less code does not require overriding any methods and can be applied to any representation. The idea is to add a CAGradientLayer as a sublayer to the UIView layer. I could not find this approach anywhere, so I would like to share.

Add a CAGradientLayer to any UIView as follows:

The category in the UIView header is UIView + Gradient.h:

 #import <UIKit/UIKit.h> @interface UIView (Gradient) -(void) addLinearUniformGradient:(NSArray *)stopColors; @end 

Category in UIView implementation of UIView + Gradient.m:

 #import "UIView+Gradient.h" #import <QuartzCore/QuartzCore.h> @implementation UIView (Gradient) -(void) addLinearUniformGradient:(NSArray *)stopColors { CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = self.bounds; gradient.colors = stopColors; gradient.startPoint = CGPointMake(0.5f, 0.0f); gradient.endPoint = CGPointMake(0.5f, 1.0f); [self.layer addSublayer:gradient]; } @end 

How to set gradient on UITableViewCell backgroundView after creating UITableViewCell :

 // Set the gradient for the cell background CGRect backgroundViewFrame = cell.contentView.frame; backgroundViewFrame.size.height = yourCellHeight; cell.backgroundView = [[UIView alloc] initWithFrame:backgroundViewFrame]; [cell.backgroundView addLinearUniformGradient:[NSArray arrayWithObjects: (id)[[UIColor redColor] CGColor], (id)[[UIColor greenColor] CGColor], nil]]; 

This example shows how to set up a simple two-column gradient (with a uniform interval). A quick look at the CAGradientLayer documentation will show you how to adjust more complex gradients.

( * EDIT ADDITIONAL IMPORTANT INFORMATION * )

Another thing to keep in mind is that if you add a gradient layer in the tableView: cellForRowAtIndexPath method, UITableViewCells are usually reused (ie [tableView dequeueReusableCellWithIdentifier: @ "foo"]). Because cells are reused, if you always add a gradient layer to the table view cell every time a cell is unloaded, you can add several gradient layers to the tableview cell during the cell's lifetime. This can be a source of performance degradation. This problem can occur without any changes in the visible results, so it is difficult to detect / observe. There are several ways to solve this problem, but one thing you can consider is to modify the source code above in addition to adding a CAGradientLayer to return the created CAGradientLayer to the caller. Then it’s quite simple to write another category method that allows you to remove the gradient layer, if it is really contained in the view:

 -(BOOL) removeGradient:(CAGradientLayer *)gradientLayer { // Search for gradient layer and remove it NSArray *layers = [self.layer sublayers]; for ( id layer in layers ) { if ( layer == gradientLayer ) { [gradientLayer removeFromSuperlayer]; return YES; } } // Failed to find the gradient layer in this view return NO; } 

Gradient removal is not required for all use cases, but if your use case leads to cell reuse, you might want to remove the gradient. One place to consider this method is the UITableViewCell prepareForReuse method.

I apologize that my original solution did not address this issue. But since this is something that can be pretty subtle, I would like to update my answer with this additional information.

+13
source share

All Articles