セルがUIImageViewサブビューを持つとき、UITableViewが不安定なスクロールを経験する

これは、今日のよりよいところで私を狂っているようにしてきました。

私はUIImageViewsでUITableViewを持っています。これらの画像ビューは、tableviewのcellForRow関数にローカルに保存されたPNGファイルをロードします。これは、画像が入っているセルがスクロールしてスクロールすると、数分の1秒間スクロールしなくなります。私はStackOverflowとgoogleの答えをトロールしましたが、私は短くなっています。だから、どんな助けも大歓迎です。

CellForRow関数のコードは次のとおりです。

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


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];



    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    if([currSection isEqualToString:@"composer"]){

        MySlide *s = [slidesArray objectAtIndex:indexPath.row];

        cell.textLabel.hidden = YES;
        UIImageView *whiteView = [[UIImageView alloc] initWithFrame:CGRectMake((projectsTable.frame.size.width/2)-150, 4, 204.8, 153.6)];

        if([s.slideImage isEqualToString:@""] || s.slideImage == nil){
            //no custom image in this cell - go with default background image

            whiteView.image = [UIImage imageNamed:@"cellback2.png"];
            whiteView.backgroundColor = [UIColor whiteColor];
        }else{
            cell.layer.shouldRasterize = YES;
            cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

            NSData *data = [[NSData alloc] initWithContentsOfFile:s.slideImage];

            UIImage *im = [[UIImage alloc] initWithData:data];


            whiteView.image = im;

            whiteView.image = [self imageWithImage:whiteView.image CovertToSize:CGSizeMake(204.8,153.6)];
            whiteView.backgroundColor = [UIColor whiteColor];

        }


        [cell.contentView addSubview:whiteView];

        [whiteView release];



        cell.accessoryType = UITableViewCellAccessoryNone;

    }


  return cell;  
}
4
これは毎回、新しいセルを作成し、イメージビューを割り当て、フォームを作成して追加するために発生します。
追加された 著者 vishy,
答えで私のコードをチェックして、私は更新しました..
追加された 著者 vishy,
if(cell == nil)文の中にwhiteBackを設定しようとしましたが、スライド画像に新しい画像パスを追加する際にimageviewの画像を更新することができませんでした。あなたはこれをどのように解決するかの簡単な例を教えてください。
追加された 著者 PinkFloydRocks,

3 答え

tableView:cellForRowAtIndexPath:がヒットするたびにではなく、セルが生成されたときに UIImageView を追加する必要があります。 @Vishyは示唆している)。次に、ドキュメントディレクトリからロードするイメージをキャッシュする必要があります( [UIImage imageNamed:] はバンドルリソースに対してこれを自動的に行います)。

@interface MyViewController() {

    NSMutableDictionary *_imageCache;
}

@end


@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];

   //other viewDidLoad stuff...

    _imageCache = [[NSMutableDictionary alloc] init];
}

- (void)viewDidUnload {
    [super viewDidUnload];

   //other viewDidUnload stuff...

    [_imageCache release];
    _imageCache = nil;
}

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        UIImageView *whiteView = [[UIImageView alloc] initWithFrame:CGRectMake((projectsTable.frame.size.width/2)-150, 4, 204.8, 153.6)];
        whiteView.tag = 111;
        whiteView.backgroundColor = [UIColor whiteColor];

        [cell.contentView addSubview:whiteView];

        [whiteView release];
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.textLabel.hidden = YES;
    }

    UIImageView* iView = (UIImageView*) [cell.contentView viewWithTag:111];


    if([currSection isEqualToString:@"composer"]) {

        MySlide *s = [slidesArray objectAtIndex:indexPath.row];

        if([s.slideImage isEqualToString:@""] || s.slideImage == nil) {

            //no custom image in this cell - go with default background image
            iView.image = [UIImage imageNamed:@"cellback2.png"];
        }
        else {

            cell.layer.shouldRasterize = YES;
            cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

           //use the image path as the cache key
            UIImage *theImage = [_imageCache objectForKey:s.slideImage];
            if (theImage == nil) {

               //load the image and save into the cache
                theImage = [UIImage imageWithContentsOfFile:s.slideImage];
                theImage = [self imageWithImage:theImage CovertToSize:CGSizeMake(204.8, 153.6)];

                [_imageCache setObject:theImage forKey:s.slideImage];
            }

            iView.image = theImage;
        }   
    }
}

@end

原則として、 tableView:cellForRowAtIndexPath:は、高速から抜け出す必要があるメソッドなので、可能な限りディスクから画像を読み込む必要はありません。

6
追加された
ありがとうございます。これは現在もユーザーがスライドショーに追加できるよりも多くの画像を扱う際にはうまくいきます。
追加された 著者 PinkFloydRocks,

以下のコードを変更してください...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

if (cell == nil) 
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    UIImageView *whiteView = [[UIImageView alloc] initWithFrame:CGRectMake((projectsTable.frame.size.width/2)-150, 4, 204.8, 153.6)];
    whiteView.tag = 111;
    whiteView.backgroundColor = [UIColor whiteColor];

    [cell.contentView addSubview:whiteView];

    [whiteView release];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.textLabel.hidden = YES;

}

UIImageView* iView = (UIImageView*) [cell.contentView viewWithTag:111];


if([currSection isEqualToString:@"composer"])
{
    MySlide *s = [slidesArray objectAtIndex:indexPath.row];

    if([s.slideImage isEqualToString:@""] || s.slideImage == nil)
    {
        //no custom image in this cell - go with default background image

        iView.image = [UIImage imageNamed:@"cellback2.png"];
    }
    else
    {
        cell.layer.shouldRasterize = YES;
        cell.layer.rasterizationScale = [UIScreen mainScreen].scale;

        iView.image = [UIImage imageWithContentsOfFile:s.slideImage];
        iView.image = [self imageWithImage:iView.image CovertToSize:CGSizeMake(204.8,153.6)];

    }   
  }
}
0
追加された
@PinkFloydRocks画像をキャッシュし、 NSArray または NSDictionary サブクラスの NSViewController サブタイトルに保存する必要があります(サイズを変更した後)。
追加された 著者 Ell Neal,
@PinkFloydRocks私は答えを投稿します
追加された 著者 Ell Neal,
セルがDocuments-folderからイメージをロードするときにスクロールがまだ停止しています。これがイメージ・データの実際のロードに関連していますか?元の画像は1024x768ですが、私のコードからわかるように、セルのサイズに対応するようにサイズが変更されています - これは多分停止を引き起こしていますか?
追加された 著者 PinkFloydRocks,
@EllNeal私は、スライドのメインイメージだけでなく、サムネイルイメージを生成することによってそれを動作させました。だから、おそらく画像のサイズとその停止を引き起こしたデータでした。好奇心の念から、画像をキャッシュする方法の小さな例を教えてください。データを配列にキャッシュして、このデータを画像の作成時に使用しますか?
追加された 著者 PinkFloydRocks,

また、UIImageが最初に表示されるまでに遅延があります。表示時間ではなくキャッシュ時間に作業を促す詳細については、この記事を参照してください。

UIImageViewのイメージプロパティを設定すると大きな遅延が発生する

0
追加された