0

画像が読み込まれていることを示すために uiimageview に「読み込み中」ビューを追加してから、ディスパッチ非同期で画像を充電し、終了したら「読み込み中」ビューを削除します。問題は、このメソッドを 2 回呼び出すと「読み込み中」ビューが 2 回追加され、2 番目のビューが削除されることはありません。

編集:

view.h で

UIView *loading;

オンビュー.m

loading = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
loading.backgroundColor = [UIColor blackColor];
loading.alpha = 0.8;
loading.layer.cornerRadius = 10;
loading.center = CGPointMake(imageView.frame.size.width/2, imageView.frame.size.height/2);

if (![imageView.subviews containsObject:loading]) {
    [imageView addSubview:loading];
}
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
    UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]]];

    dispatch_sync(dispatch_get_main_queue(), ^{
        if (image) {
            [imageView setImage:image];
            [imageView setNeedsLayout];
            if ([imageView.subviews containsObject:loading]) {
                [loading removeFromSuperview];
            }
        }
    });
});

これが一度だけ呼び出された場合、またはロードが既に削除された後に呼び出した場合、すべて正常に機能します。問題は、ブロックが終了する前にこれを呼び出した場合です。

みんなありがとう、これが私の最終的な解決策です。

if (!blackView) {
UIActivityIndicatorView *load = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
blackView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
blackView.backgroundColor = [UIColor blackColor];
blackView.alpha = 0.8;
blackView.layer.cornerRadius = 10;
blackView.center = CGPointMake(fotoVisual.frame.size.width/2, fotoVisual.frame.size.height/2);
load.center = CGPointMake(blackView.frame.size.width/2, blackView.frame.size.height/2);
[load startAnimating];
[blackView addSubview:load];


[fotoVisual setImage:[UIImage imageNamed:@"previewImagen.png"]];
descripcionFotoView.text = [selectedImage objectForKey:@"titulo"];

}
if (![fotoVisual.subviews containsObject:blackView]) {
    [fotoVisual addSubview:blackView];
}
dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{
    [fotoVisual setImageWithURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]
               placeholderImage:[UIImage imageNamed:@"previewImagen.png"]];
    dispatch_async(dispatch_get_main_queue(), ^{
            [blackView removeFromSuperview];
            blackView = nil;
    });
});
dispatch_release(downloadFoto);
4

2 に答える 2

2

あなたが抱えている問題は、loading毎回新しいビューを作成しているように見えますが、これはあなたが望むものではありません. 毎回[imageView.subviews containsObject:loading]新しいビューを作成するため、あなたは決して真実ではありません。loading

このようなチェックを行うように作成ロジックを変更できます

if (!loading) {
  // configure loading
  [imageView addSubview:loading];
}

次に、コールバックを次のように変更します

dispatch_sync(dispatch_get_main_queue(), ^{
  if (image) {
    [imageView setImage:image];
    [imageView setNeedsLayout];
    [loading removeFromSuperview];
    loading = nil;
  }
});

dispatch_syncの代わりに使用している特定の理由はありますdispatch_asyncか?

于 2014-05-26T19:56:58.603 に答える
1

loadingサブビューをdispatch_asyncブロックに追加

dispatch_queue_t downloadFoto = dispatch_queue_create("Get Photo", NULL);
dispatch_async(downloadFoto, ^{

if (!loading.superview) {
// we assume your loading view doesn't have a superview so we can add it to imageView
   dispatch_sync(dispatch_get_main_queue(), ^{        
     [imageView addSubview:loading];
  };
}

    UIImage *image = [[UIImage alloc]initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]]];


        if (image) {
          dispatch_sync(dispatch_get_main_queue(), ^{
            [imageView setImage:image];
            [imageView setNeedsLayout];
            if ([imageView.subviews containsObject:loading]) {
                [loading removeFromSuperview];
            }
          });
        }
});

非同期イメージのダウンロードには、 SDWebimageも使用でき ます。プロジェクトをダウンロードし、SDWebimage フォルダーをプロジェクトに追加して、次のように使用します。

#import "UIImageView+WebCache.h"

[self.imageView setImageWithURL:[NSURL URLWithString:[selectedImage objectForKey:@"url"]]
                   placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

これにより、画像もキャッシュされます。

于 2014-05-26T19:33:37.507 に答える