2010-07-18 63 views
7

我想创建一个渐变UITableViewCell背景,就像iPhone上默认的Clock应用程序一样。我不确定如何实现这一点。我是否创建图片并将其设置为:如何设置渐变UITableViewCell背景?

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

或者是否有其他更好的方法?

+0

我认为这是唯一的方法 – tadejsv 2010-07-18 17:39:55

+1

如果我的身高不是相同的大小?我如何创建我的背景图形? – 2010-07-18 18:04:46

回答

13

我发现现有的回答这个问题,但并不满足。这是一种替代方法,它需要更少的代码,不需要重写任何方法,并且可以应用于任何视图。这个想法是将一个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的backgroundView上设置渐变廷UITableViewCell

// 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方法。

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

+0

我试图将它应用到分组单元格,但渐变填充是没有圆角的框。我错过了什么? – Claus 2012-05-15 11:49:35

+0

嗯,你可能需要设置图层半径/蒙版。阅读有关以下两种方法的文档: [self.layer setCornerRadius:10.0]; [self.layer setMasksToBounds:YES]; 希望你能指出正确的方向。 – Chris 2012-05-16 07:12:51