0

私はテーブルビューを持っており、各セルにグラデーションの背景があり、セルが同じサイズの場合に機能します。別のデータセットと可変セルサイズに同じテーブルビューを使用します。カスタムセルのinitwithcoder内にグラデーションコードを配置すると、元のセルのサイズのグラデーションが作成されます。別のことを試しましたが、適切なサイズを取得できませんでした。唯一の答えは、テキストに基づいてセルを計算するメソッドから取得したセルの高さを使用して、cellForRowAtIndexPath内に一時フレームを作成することでした。cellForRowAtIndexPath内でセルの高さが正しくない理由を理解しようとしています。これを明確にするためのコードを次に示します。

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

//バックグラウンドビューなしで新しいコードで更新します

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

2 に答える 2

0

ここでは多くのことが起こっていますが、この場合、フレームの原点が間違っています。グラデーションの位置をcontentViewの位置に設定しますが、その位置はcontentViewの親を基準にしており、実際に必要なのはcontentViewの0,0から開始することです。サイズのみが表示されるため、フレームとして使用できますcontentView.bounds。位置は0です。

私がチェックするもう1つのことは、テーブルビューがセルに新しいフレームを適用するときにサイズ変更されない場合に備えて、グラデーションビューのマスクの自動サイズ変更です。

于 2012-11-21T04:27:42.660 に答える
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];

}
于 2012-11-21T07:42:47.120 に答える