2

ViewController が所有するグループ化された UITableview で UITableViewCells のカスタム背景画像を設定することが原因であることがわかります。

私は、この他の SO の質問に記載されている推奨事項に従っていると思います: iPhone UITableView のスクロール パフォーマンスを改善するための秘訣

また、愚かなことをしていないことを確認するために、この記事に従っています: Cocoa With Love Custom UITableView Drawing

バックグラウンド スタイル コードを呼び出さなくてもすぐに、パフォーマンスが向上します。

提案に従って、次のすべての手順を実行しています。

  • デザインの都合上、2 つの異なるセル バリエーションがあり、行の高さを均一にすることはできません。セルのバリエーションに関係なく、行の背景は常に 3 つの画像のうちの 1 つであり、行のインデックスに基づいています。0: top_row_image、n-1: bottom_row_image、その他すべて: middle_row_image
  • ViewController の viewDidLoad で背景に使用する画像を読み込んでいます。
  • セル内のUITextFieldにそれを処理させているので、drawRectコードはありません
  • セルのレイヤーは不透明に設定されています
  • セル識別子が再利用されています
  • NIB ファイルからセルをロードしない

基本的に、行タイプのタイプに応じて、テーブルのセクションの各行を、上、中、下の行の背景画像でスタイルしたいと考えています。UITableView にカスタム背景を設定するためのより良い方法を提案できる人はいますか?

これが私のコードです:

ViewController:
@property (nonatomic, weak) IBOutlet                            *tableview;
@property (nonatomic, strong, readwrite) UIImage                *topRowImage;
@property (nonatomic, strong, readwrite) UIImage                *middleRowImage;
@property (nonatomic, strong, readwrite) UIImage                *bottomRowImage;

@synthesize tableview = _tableview;    
@synthesize topRowImage = _topRowImage;         
@synthesize middleRowImage = _middleRowImage;
@synthesize bottomRowImage = _bottomRowImage;

// Load the images that will be used for the cell background ahead of time
- (void)viewDidLoad
{
    [super viewDidLoad];        

    // All of the images are 60x20 but my cells are 300x44 or 300x56
    UIEdgeInsets edgeInsets = UIEdgeInsetsMake(2, 4, 2, 4);        
    self.topRowImage = [[UIImage imageNamed:@"top_row.png"] resizableImageWithCapInsets:edgeInsets];        

    UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0, 4, 0, 4);
    self.middleRowImage = [[UIImage imageNamed:@"middle_row.png"] resizableImageWithCapInsets:edgeInsets];            

    edgeInsets = UIEdgeInsetsMake(2, 4, 2, 4);
    self.bottomRowImage = [[UIImage imageNamed:@"bottom_row.png"] resizableImageWithCapInsets:edgeInsets];    
}

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellId = [self getCellIdAt:indexPath];

    BaseCustomTableViewCell *cell = (BaseCustomTableViewCell *)[aTableView dequeueReusableCellWithIdentifier:cellId];

    if (cell == nil) 
    {
        if ([cellId isEqualToString:@"CellId1"])
        {
           cell = [[CustomTableViewCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];     
        }
        else
        { 
           cell = [[CustomTableViewCell2 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];     
        }
    }

    // the following line seems to be the bottleneck
    [self styleBackground:cell indexPath:indexPath totalRows:totalRows];

    [cell configureData:myRowData];
}

- (void)styleCellBackground:(BaseCustomTableViewCell *)cell 
                  indexPath:(NSIndexPath *)indexPath
                  totalRows:(NSInteger)totalRows
{
    UIImage *backgroundImage = nil;    

    if (indexPath.row == 0)
    {
        // Top row of this section        
        backgroundImage = self.topRowImage; // ivar loaded during 'viewDidLoad'
    }
    else if (indexPath.row == totalRows - 1)
    {
        // Bottom row of this section        
        backgroundImage = self.bottomRowImage;
    }
    else {
        // Middle row of this section        
        backgroundImage = self.middleRowImage;
    }

    [cell updateRowBackground:backgroundImage];
}

@implementation CustomTableViewCell

-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
    {        
        // Create my text field
        _textField = [[UITextField alloc] initWithFrame:CGRectZero];        
        _textField.backgroundColor          = [UIColor whiteColor];    

        self.backgroundColor                = [UIColor whiteColor];            
        self.contentView.backgroundColor    = [UIColor whiteColor];

        self.backgroundView = [[UIImageView alloc] init];        

        // not sure which of these should be set to opaque to ensure to meet criteria #4
        // 4. Make your UITableViewCell's layer opaque (same goes for the content view if you have one)
        self.backgroundView.opaque = YES;
        self.layer.opaque = YES;
        self.opaque = YES;        
        self.contentView.opaque = YES;        

        [self.contentView addSubview:_textField];
    }
}

- (void)layoutSubviews
{    
    CGRect textFieldFrame = CGRectMake(10, 2, 278, 40);
    self.textField.frame = textFieldFrame;

    [super layoutSubviews];
}

- (void)updateRowBackground:(UIImage *)rowBackground
{
    ((UIImageView *)self.backgroundView).image = rowBackground;        
}
4

1 に答える 1

0

を呼び出すたびにすべてのセルの背景画像を切り替えるのをやめると、パフォーマンスが大幅に向上すると思いますcellForRowAtIndexPath

3種類の細胞(「上」、「中」、「下」)があるようですね。それらを交換して再利用するのをやめることができるため、使用するたびに背景画像をリセットする必要があります。

代わりに、テーブル内の位置に応じて異なる識別子でテーブル セルのインスタンスを初期化できます。このようにして、"top" 識別子を持つ単一のセル、"bottom" 識別子を持つ単一のセル、および "middle" 識別子を持つ多数のセルを作成します。その後、セルを初期化するときにのみ背景画像を設定できます。適切な識別子でセルを再利用しようとする限り、背景画像を毎回変更する必要はありません。

于 2012-09-11T01:08:24.253 に答える