如何设置渐变UITableViewCell背景?

时间:2010-07-18 17:26:15

标签: iphone objective-c cocoa-touch uitableview

我想创建一个渐变UITableViewCell背景,就像iPhone上的默认Clock应用程序一样。我不确定如何实现这一目标。我是否创建了一个图像并进行了设置:

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

还是有其他/更好的方法吗?

2 个答案:

答案 0 :(得分:14)

我找到了这个问题的现有答案,但并不满意。这是一种替代方法,需要更少的代码,不需要覆盖任何方法,并且可以应用于任何视图。我们的想法是将CAGradientLayer作为子图层添加到UIView的图层中。我无法在任何地方找到这种方法,所以我想分享。

CAGradientLayer添加到任何UIView,如下所示:

UIView标题上的类别 - UIView + Gradient.h:

#import <UIKit/UIKit.h>

@interface UIView (Gradient)
-(void) addLinearUniformGradient:(NSArray *)stopColors;
@end

UIView实施的类别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

如何在创建UITableViewCell之后在UITableViewCell的backgroundView上设置渐变:

// Set the gradient for the cell's 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]];

此示例仅显示如何设置简单的两停梯度(具有均匀间距)。快速查看CAGradientLayer文档将向您展示如何设置更复杂的渐变。

*编辑其他重要信息*

要记住的另一件事是,如果你在像tableView:cellForRowAtIndexPath这样的方法中添加渐变层,则通常会重用UITableViewCells(即[tableView dequeueReusableCellWithIdentifier:@“foo”])。由于正在重复使用单元格,如果每次单元格出列时始终向表格视图单元格添加渐变图层,则最终可能会在单元格的生命周期内向tableview单元格添加多个渐变图层。这可能是性能降低的原因。在没有任何可见结果变化的情况下可能会出现此问题,因此可能难以检测/观察。有几种方法可以解决这个问题,但您可以考虑做的一件事是修改上面的原始代码,以及添加CAGradientLayer,以将创建的CAGradientLayer返回给调用者。然后编写另一个类别方法非常简单,如果它实际包含在视图中,则允许删除渐变图层:

-(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;
}

并非所有用例都需要删除渐变,但如果您的用例导致单元格重用,则可能需要考虑删除渐变。考虑调用此方法的一个地方是来自UITableViewCell的prepareForReuse方法。

我很抱歉我原来的解决方案没有解决这个问题。但由于它可能非常微妙,我想用这些附加信息更新我的答案。

答案 1 :(得分:7)