Adding Fading Gradients to UITableView
Jason Jardim asked (4 Months ago): This is just a screen shot I found with someone posting a similar question. I am trying to fade out he top/ bottom cells in a tableview. How do I achieve this effect? First of all, Jason, I am sorry it took so long. I was extremely busy during the past few months but I kept your e-mail at the bottom of my inbox as something that I am really interested in to give a good answer to. Let me make it up for you by proposing several solutions to your question as well as show one that I find the coolest. First of all by looking at the sample screenshot we see that there is a border around the table view. This tells us that the table view does not fill the entire screen but there is obviously an imageView responsible for the ornamentals surrounding the table view. If we go with this imageView then the next question is whether the image is below or above the table view itself. The first instinct might be “below!” but that can be treacherous and cause you more work than is actually needed to achieve this effect. You could just as well have the part for the table view “cut out” in the image, i.e. have the center portion be Alpha 0 and the top and bottom would be an alpha gradient from 100% to 0%. A designer versed with Photoshop could easily create something like this for you. Then you put this imageView on top of your table view, size the table view to fit inside the border. Finally you will want to make sure that userInteraction is disabled on the imageView, because otherwise no touches would be reaching the table view. While this solution is simple it does not satisfy me personally. As developer I want to achieve such an effect entirely in code because then it has the added advantage of being independent or resolution or interface orientation. The first thing we’ll try is to mask the layer of the table view. On iOS each UIView has a CALayer that takes care of the actual drawing. And each CALayer has a mask property where you can set another layer to mask out parts of the host layer. For masking layers it does not matter which colors you use because only the alpha value of each pixel is considered for the composition. 100% alpha means that a layer pixel shows fully, 0% alpha causes a layer pixel to be transparent. For this tutorial I created a new navigation-based app without CoreData. We also need the QuartzCore.framework for the advanced layer handling methods. A useful layer type for this purpose is CAGradientLayer which exists since iOS version 3.0. RootViewController.h #import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> @interface RootViewController : UITableViewController { CAGradientLayer *maskLayer; } @end For the sake of simplicity we create the mask in viewWillAppear because at this point the table view has already been resized to the proper size. If we would create it earlier (or if you plan to support different sizes) then you would also need code to adjust the layer bounds to fit. – (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (!maskLayer) { maskLayer = [CAGradientLayer layer]; CGColorRef outerColor = [UIColor colorWithWhite:1.0 alpha:0.0].CGColor; CGColorRef innerColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor; maskLayer.colors = [NSArray arrayWithObjects:(id)outerColor, (id)innerColor, (id)innerColor, (id)outerColor, nil]; maskLayer.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.2], [NSNumber numberWithFloat:0.8], [NSNumber numberWithFloat:1.0], nil]; maskLayer.bounds = CGRectMake(0, 0, self.tableView.frame.size.width, self.tableView.frame.size.height); maskLayer.anchorPoint = CGPointZero; self.view.layer.mask = maskLayer; } } We only create the layer once. Since there can be only one mask layer at a time we combine the top and the bottom gradient into one where the outer areas will be 20% of the entire height. The default anchor point is the center of the layer, so we change that to the top left. If we stopped here then you would get the gradients, but they would move together with the contents of the table view. Luckily table views are UIScrollView child classes and thus you can also implement the UIScrollViewDelegate methods. We are using the one that fires on each movement to adjust the position of the masking layer. – (void)scrollViewDidScroll:(UIScrollView *)scrollView { [CATransaction begin]; [CATransaction setDisableActions:YES]; maskLayer.position = CGPointMake(0, scrollView.contentOffset.y); [CATransaction commit]; } Note that we also need to disable actions because position is an animatable property on CALayer. If you set that this triggers an implicit animation which would cause the masking layer to lag behind. With actions disabled the layer position is set right away. There’s another problem that only becomes apparent if you start scrolling and the vertical scroll bar shows: it is also affected by the mask which you probably don’t want because it looks weird. So … Continue reading Adding Fading Gradients to UITableView
Copy and paste this URL into your WordPress site to embed
Copy and paste this code into your site to embed