0

100個のリモート画像を表示していますtableview

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {


//static NSString *CellIdentifier = @"Cell";
NSString *CellIdentifier = [NSString stringWithFormat:@"%d",indexPath.row];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

}

cell.imageView.image = nil;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
cell.selectionStyle = UITableViewCellSelectionStyleNone;


// Configure the cell...

for (UIView *view in cell.contentView.subviews) {
    if ([view isKindOfClass:[UIButton class]] || [view isKindOfClass:[UILabel class]]||[view isKindOfClass:[UIImageView class]]) {
        [view removeFromSuperview];
    }
}

int imageNumber = 0;

if (isInSearchMode)
{
    PhotoVO *photoVO = (PhotoVO *)[searchResultArray objectAtIndex:indexPath.row];

    UIImageView *photo_View = [[UIImageView alloc]initWithFrame:CGRectMake(20, 5, width , height - 10)];
    photo_View.tag = 101;
    [[photo_View layer] setBorderWidth:3.0f];
    [[photo_View layer] setBorderColor:[UIColor whiteColor].CGColor];
    [photo_View setImageWithURL:[NSURL URLWithString:photoVO.thumb_URL1] placeholderImage:[UIImage imageNamed:@"loader"]];


    [cell.contentView addSubview:photo_View];

    UILabel *stringLable=[[UILabel alloc]initWithFrame:CGRectMake(130, 20, 150, 30)];
    stringLable.backgroundColor=[UIColor clearColor];
    stringLable.text=photoVO.photoName;
    stringLable.font=[UIFont systemFontOfSize:16.0];
    [cell.contentView addSubview:stringLable];

    UILabel *tagLable=[[UILabel alloc]initWithFrame:CGRectMake(130, 55, 150, 30)];
    tagLable.backgroundColor=[UIColor clearColor];
    tagLable.text=photoVO.tagString;
    tagLable.font=[UIFont systemFontOfSize:12.0];

    [cell.contentView addSubview:tagLable];


}
else
{

    for (int i = (indexPath.row * imagesCount); i < ((indexPath.row *imagesCount) + imagesCount); i++) {

        if (i < [cellImageVOArray count]) { // If resultsArray Count is odd then we no need to create cell image

            PhotoVO *photoVo = (PhotoVO *)[cellImageVOArray objectAtIndex:i];

            UIButton *appIconBtn = [UIButton buttonWithType:UIButtonTypeCustom];

            appIconBtn.frame = CGRectMake(((imageNumber * 5)+5)+(imageNumber * width), 2, width, height -4);

            appIconBtn.tag = i + 100;
            [[appIconBtn layer] setBorderWidth:3.0f];
            [[appIconBtn layer] setBorderColor:[UIColor whiteColor].CGColor];

            [appIconBtn addTarget:self action:@selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];

            [appIconBtn setBackgroundImageWithURL:[NSURL URLWithString:photoVo.thumb_URL1] placeholderImage:[UIImage imageNamed:@"loader.png"]];

            //[appIconBtn setBackgroundImageWithURL:[NSURL URLWithString:photoVo.thumb_URL1]];

            [cell.contentView addSubview:appIconBtn];
            imageNumber ++;

        }

    }



}

return cell;

}

で画像を表示するために上記のコードを使用していますがtableView、チェックするすべての方法でメモリ警告が表示されます。セルは毎回作成していると思いますので、コードに問題があれば教えてください。

4

2 に答える 2

5

これは問題です:NSString *CellIdentifier = [NSString stringWithFormat:@"%d",indexPath.row];

各セルに新しい識別子を作成しているため、何も再利用していません。いくつかの異なるセル スタイルを再利用できるようにしても問題ありませんが、行ごとに新しいセルを作成しているだけです。

次に、ここで何をしているのかを考える必要があります。

for (UIView *view in cell.contentView.subviews) {
    if ([view isKindOfClass:[UIButton class]] || [view isKindOfClass:[UILabel class]]||[view isKindOfClass:[UIImageView class]]) {
        [view removeFromSuperview];
    }
}

セルが必要になるたびに、セルを構成する部品を取り外し、その後すぐに再作成します。で可能な限り再利用する必要がありますUITableView。必要な部分を備えた のカスタム サブクラスの作成を検討してUITableViewCellから、それを使用する必要があります。そうは言っても、デフォルトの画像と2つのラベルしかないように見えるUITableViewCellので、セルが非常にカスタムでない限り、それらを作成する必要はおそらくないでしょう。

最後に、何を行っているかを確認する必要がありますisInSearchMode。現在、基本的にテーブル全体の if ステートメントがあります。それは恐ろしいことではありませんが、そうする場合は、可能なセルごとに1つずつ、2つのセル識別子が必要です。次に、ifステートメントでセル識別子を交換し、適切なデータを入力します。

何よりも、可能な限り(あなたの場合のようです)、このメソッドで新しいビューをまったく作成しないでください。あなたはそれをUITableViewCell処理する必要があります。

カスタム セルの作成

の単純なサブクラスから始めUITableViewCellます。UILabel次に、やなど、必要なカスタム パーツごとにプロパティを追加できますUIImageView。また、これらをオーバーライドinitして作成することも、オンデマンドで作成するカスタム プロパティ ゲッターに配置することもできます。

//  CustomCell.h
#import <UIKit/UIKit.h>

@interface Custom : UITableViewCell

@property (strong, nonatomic) UILabel *titleLabel;

@end

//  CustomCell.m
#import "CustomCell.h"

@implementation CustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(12.0, 10.0, self.contentView.frame.size.width - 24.0, 22.0)];
        [self.titleLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
        [self.titleLabel setHighlightedTextColor:[UIColor whiteColor]];
        [self.titleLabel setFont:[UIFont boldSystemFontOfSize:17.0]];
        [self.titleLabel setBackgroundColor:[UIColor clearColor]];
        [self.titleLabel setTextColor:[UIColor blackColor]];
        [self.titleLabel setAdjustsFontSizeToFitWidth:YES];
        [self.titleLabel setMinimumFontSize:8.0];

        [self.contentView addSubview:self.titleLabel];
    }
    return self;
}

@end

cellForRowAtIndexPath:次に、カスタム クラスを使用するように書き換えるだけです。あなたの場合、2 つのカスタム セルを使用して、それらを切り替えることができます。これにより、オンデマンドで必要なだけの各セルが作成され、画面上または画面外に移動するときに再利用されます。

static NSString *CellIdentifier = @"Cell";
static NSString *SearchCellIdentifier = @"SearchCell";

if (isInSearchMode) {
    SearchCell *cell = (SearchCell *)[tableView dequeueReusableCellWithIdentifier:SearchCellIdentifier];

    if (cell == nil) {
        cell = [[SearchCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    cell.titleLabel = @"Custom Search Title";

} else {
    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    cell.titleLabel = @"Custom Title";

}

これは、アプリケーションの動作に応じてさらに簡単にリファクタリングできますが、これで正しい道をたどることができます。

于 2013-03-12T12:40:35.947 に答える
0

はい、行ごとに異なるセル識別子があるため、再利用は行われません。

変化する:

NSString *CellIdentifier = [NSString stringWithFormat:@"%d",indexPath.row];

NSString *CellIdentifier = @"CellId";
于 2013-03-12T12:40:51.953 に答える