2012-11-21 29 views
0

我有tableview,其中每個單元格都有一個漸變背景,並且它在單元格的大小相同時起作用。我使用相同的tableview查看另一個數據集和可變的單元大小。如果我將漸變代碼放在自定義單元格的initwithcoder中,那麼它會爲原始單元格的大小創建一個漸變。我嘗試了不同的東西,但無法獲得合適的尺寸。唯一的答案是在cellForRowAtIndexPath中創建一個臨時框架,其中單元格的高度來自基於文本計算它的方法。我想弄清楚爲什麼cellForRowAtIndexPath中單元格的高度不正確。這是使其更清晰的代碼。在cellForRowAtIndexPath中獲取cell.contentView高度以創建漸變背景

- (UITableViewCell *)tableView:(UITableView *)tableView 
      cellForRowAtIndexPath:(NSIndexPath *)indexPath 
          object:(PFObject *)object 
    { 
     static NSString *CellIdentifier = @"feedCell"; 
     FeedTableViewCell *cell = (FeedTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[FeedTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
     } 
     [[cell.contentView viewWithTag:999]removeFromSuperview]; 
     // Configure the cell... 
     UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:16.0]; 
     cell.signText.font = cellFont; 
     CGRect lblFrame = cell.signText.frame; 
     lblFrame.size.height = [self labelHeightForText:[object objectForKey:@"text"]]; 
     cell.signText.frame = lblFrame; 
     cell.signText.lineBreakMode = NSLineBreakByWordWrapping; 
     cell.signText.text = [object objectForKey:@"text"]; 
     UIColor *grayLightOp = [UIColor colorWithRed:0.863 green:0.841 blue:0.812 alpha:1.000]; 
     CAGradientLayer *gradient = [CAGradientLayer layer]; 
//here is the tempFrame that i am talking about i can't just set tempFrame = cell.contentView.frame 
     CGRect tempFrame = CGRectMake(cell.contentView.frame.origin.x, cell.contentView.frame.origin.y, cell.contentView.frame.size.width, [self labelHeightForText:[object objectForKey:@"text"]]); 
     gradient.frame = tempFrame; 
     gradient.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor, (id)grayLightOp.CGColor, nil]; 
     UIView *backgroundView = [[UIView alloc]initWithFrame:gradient.frame]; 
     backgroundView.tag = 999; 
     [backgroundView.layer insertSublayer:gradient above:0]; 
     [cell.contentView insertSubview:backgroundView atIndex:0]; 
     [cell.backgroundView setNeedsDisplay]; 
     return cell; 
    } 

    -(CGFloat)labelHeightForText:(NSString *)text 
    { 
     UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:16.0]; 
     CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT); 
     CGSize labelSize = [text sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping]; 
     return labelSize.height + 20; 
    } 

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     PFObject *feedObject = [self objectAtIndexPath:indexPath]; 
     NSString *cellText = [feedObject objectForKey:@"text"]; 
     return [self labelHeightForText:cellText]; 
    } 

======更新 我評論出的cellForRowAtIndexPath梯度的創建,這裏是從自定義單元格的代碼。我想我必須調整漸變本身,而不是背景視圖。當我這樣做時,漸變大小是正確的,但是當我滾動時,我看到這個快速的動畫漸變正在繪製細胞進入視圖時。我能做些什麼嗎?

@interface FeedTableViewCell() 

@property (nonatomic, strong)CAGradientLayer *cellGradient; 

@end 

@implementation FeedTableViewCell 

@synthesize signText = _signText; 
@synthesize personName = _personName; 
@synthesize personImageView = _personImageView; 
@synthesize cellGradient = _cellGradient; 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     // Initialization code 
    } 
    return self; 
} 
-(id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 

    if (self) { 
     UIColor *grayLightOp = [UIColor colorWithRed:0.863 green:0.841 blue:0.812 alpha:1.000]; 
     self.cellGradient = [CAGradientLayer layer]; 

     self.cellGradient.frame = self.contentView.frame; 
     self.cellGradient.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor, (id)grayLightOp.CGColor, nil]; 
     UIView *backgroundView = [[UIView alloc]initWithFrame:self.cellGradient.frame]; 
     backgroundView.tag = 998; 
     [backgroundView.layer insertSublayer:self.cellGradient above:0]; 
     self.backgroundView = backgroundView; 
     //[self.layer insertSublayer:gradient atIndex:0]; 

    } 
    return self; 
} 

-(void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    [CATransaction begin]; 
    [CATransaction setDisableActions:YES]; 
    self.cellGradient.frame = self.contentView.frame; 
    [CATransaction commit]; 
} 

//更新與新代碼與出backgroundview

-(id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 

    if (self) { 
     UIColor *grayLightOp = [UIColor colorWithRed:0.863 green:0.841 blue:0.812 alpha:1.000]; 
     CAGradientLayer *gradient = [CAGradientLayer layer]; 
     gradient.frame = self.frame; 
     gradient.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor, (id)grayLightOp.CGColor, nil]; 
     /*UIView *backgroundView = [[UIView alloc]initWithFrame:gradient.frame]; 
     [backgroundView.layer insertSublayer:gradient above:0]; 
     self.backgroundView = backgroundView; 
     [backgroundView.layer insertSublayer:gradient atIndex:0];*/ 
     [self.layer insertSublayer:gradient atIndex:0]; 
    } 
    return self; 
} 

回答

0

一次創建漸變圖層,理想情況下是在單元的init方法中。在單元格的layoutSubviews方法中調整大小(首先調用super)。

您現在這樣做的方式會導致較差的滾動性能,因爲您每次都在重新創建漸變圖層。

更新後的問題中的代碼幾乎沒問題,但是您可以看到漸變調整大小的動畫。這是因爲您正在更改CALayer的動畫屬性 - 這些更改默認爲動畫。您可以通過將更改包裝在CATransaction中並禁用隱式動畫來防止此問題:

-(void)layoutSubviews 
{ 
    [super layoutSubviews]; 
    NSArray *layers = [self.backgroundView.layer sublayers]; 
    CAGradientLayer *gradient = [layers objectAtIndex:0]; 

    [CATransaction begin]; 
    [CATransaction setDisableActions:YES]; 
    gradient.frame = self.contentView.frame; 
    [CATransaction commit]; 

} 
+0

感謝您的回覆。我使用自定義單元中的代碼更新了問題。當我滾動時,我看不到任何性能問題,但我寧願通過在init中繪製漸變來使其工作。 – Yan

+0

查看編輯答案。 – jrturton

+0

完美!謝謝!這是一個更好,更乾淨的解決方案。只是一個問題。漸變總是會是圖層的objectAtIndex:0?我在做insertSublayer:上面的梯度:0];可以設置漸變層大於0嗎? – Yan

0

有很多怎麼回事,但是你的框架的起源是錯誤在這種情況下。您將漸變的位置設置爲contentView位置,但該位置與contentView的父級相對,並且您實際需要的是在012處開始 contentView在0,0。你可以使用contentView.bounds作爲你的框架,因爲這隻給你的大小,位置爲0.

我會檢查的另一件事是自動調整屏蔽梯度視圖,以防它在tableview將新框架應用到單元格時沒有調整大小。