AssetsLibraryを使用してiPhoneのすべての画像を取得しました。画像ビューでUIImageオブジェクトを渡し、スクロールビューで画像を表示しています。iPhoneには200を超える画像があり、ページングを使用せずにすべての画像をスクロールビューで垂直に表示する必要があります。これには画像の表示に時間がかかり、メモリの問題もあります。scrollviewでiphone画像を遅延ロードするためのコードはありますか
4 に答える
私は最近これに取り組んでおり、Web で多数のサンプル コードをチェックアウトしました。どれも (主張にもかかわらず) 遅延読み込みを実際に実行したり、私が我慢したかったよりもはるかに複雑 (不必要なベルとホイッスル) を持っていませんでした。PhotoPicker の Apple WWDC ビデオは、遅延読み込みを示しているように見えますが、事前にスライスされた画像のタイリングに重点を置いているように見えるため、あまり役に立ちません。
私がやったことはaspectThumbnails
、一度にすべてをロードすることです。それらは小さく、それほど多くのメモリを占有しないためです。次に、fullScreenImage
オンデマンドで表現をロードし、imageView がオフスクリーンになるようにscrollViewDidEndDecelerating
リロードします。aspectThumbnail
効果は非常に流動的で視覚的です。画像は少し粗くなり、すぐに (バックグラウンドの読み込みによって) 解像度の高い画像に置き換えられます。
おそらく、より洗練されたものを使用できます-おそらく、currentPage +1 & -1 のフル解像度の画像をロードします。私はまだそれに慣れていません。また、ブロックの使用が最適かどうかは完全にはわかりませんが、エラーは発生しません。
これを Segue から呼び出し、ルート viewControllerassetsArray
のメソッド内から (ALAssets の NSArray) を設定します。prepareForSegue:
// ScrollViewController.h
#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface ScrollViewController : UIViewController <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (strong, atomic) ALAssetsLibrary* assetLibrary;
@property (nonatomic,strong)NSMutableArray* assetsArray;
@end
//ScrollViewController.m
#import "ScrollViewController.h"
@interface ScrollViewController ()
@property (nonatomic,assign) CGSize currentImageSize;
@property (nonatomic, assign)int currentPages;
@property (nonatomic, assign)int currentPageNum;
@property (nonatomic, strong)UIImage* placeHolder;
@end
@implementation ScrollViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//self.placeHolder = [UIImage imageNamed:@"loader.jpg"];
self.scrollView.delegate = self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.assetsArray != nil) {
self.currentPages = [self.assetsArray count];
CGSize size = self.scrollView.frame.size;
int num = self.currentPages;
self.scrollView.contentSize=CGSizeMake(size.width*num, size.height);
[self loadThumbnails];
self.currentPageNum = 0;
[self loadFullScreenImageByIndex:self.currentPageNum];
}
}
-(void)loadThumbnails
{
int pageCount = self.currentPages;
CGSize size = self.scrollView.frame.size;
self.scrollView.contentSize=CGSizeMake(size.width*pageCount, size.height);
for (int i = 0; i < pageCount; i++) {
ALAsset *asset = [self.assetsArray objectAtIndex:i];//
CGRect imageViewFrame;
// x offset is determined by arrayIndex
imageViewFrame.origin.x = self.scrollView.frame.size.width * i;
imageViewFrame.origin.y = 0;
imageViewFrame.size = self.scrollView.frame.size;
self.currentImageSize = imageViewFrame.size; // THIS IS WRONG
UIImage *image = [[UIImage alloc] initWithCGImage:asset.aspectRatioThumbnail];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.clipsToBounds = YES;
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.frame = imageViewFrame;
imageView.tag = i+1;// start tags at 1
[self.scrollView addSubview:imageView];
}
}
- (void)viewDidUnload {
[self setScrollView:nil];
[super viewDidUnload];
}
- (void)loadFullScreenImageByIndex:(int)index
{
int arrayIndex = index;
int tagNumber = index+1;
ALAsset *asset = [self.assetsArray objectAtIndex:arrayIndex];
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage];
__strong __typeof__(weakSelf) strongSelf = weakSelf;
if ([strongSelf.scrollView viewWithTag:tagNumber] != nil){
dispatch_async(dispatch_get_main_queue(), ^{
__strong __typeof__(weakSelf) strongSelf = weakSelf;
if ([strongSelf.scrollView viewWithTag:tagNumber]!= nil){
UIImageView * tmpImageView = (UIImageView*)[strongSelf.scrollView viewWithTag:tagNumber];
tmpImageView.image = tmpImage;
}
});
}
});
}
- (void)loadThumbnailImageByIndex:(int)index
{
int arrayIndex = index;
int tagNumber = index+1;
ALAsset *asset = [self.assetsArray objectAtIndex:arrayIndex];//
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
UIImage *tmpImage = [[UIImage alloc] initWithCGImage:asset.aspectRatioThumbnail];
__strong __typeof__(weakSelf) strongSelf = weakSelf;
if ([strongSelf.scrollView viewWithTag:tagNumber] != nil){
dispatch_async(dispatch_get_main_queue(), ^{
__strong __typeof__(weakSelf) strongSelf = weakSelf;
if ([strongSelf.scrollView viewWithTag:tagNumber]!= nil){
UIImageView * tmpImageView = (UIImageView*)[strongSelf.scrollView viewWithTag:tagNumber];
tmpImageView.image = tmpImage;
}
});
}
});
}
- (void)manageImages
{
int currentPage = (self.scrollView.contentOffset.x / self.currentImageSize.width);
if (currentPage != self.currentPageNum){
[self loadThumbnailImageByIndex:self.currentPageNum]; //pg no longer visible so load thumb
[self loadFullScreenImageByIndex:currentPage]; // load full
self.currentPageNum = currentPage;// store
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self manageImages];
}
GCDブロックとグランドセントラルディスパッチを使用できます。.hファイルで宣言します
dispatch_queue_t imageQueue_;
NSmutableDictionaryを作成する
@property (nonatomic, strong) NSMutableDictionary *thumbnailsCache;
以下のコードを使用して画像を表示します。
NSString *thumbnailCacheKey = [NSString stringWithFormat:@"cache%d",imageIndex];
if (![[self.thumbnailsCache allKeys] containsObject:thumbnailCacheKey]) {
// thumbnail for this row is not found in cache, so get it from remote website
__block NSData *image = nil;
dispatch_queue_t imageQueue = dispatch_queue_create("queueForCellImage", NULL);
dispatch_async(imageQueue, ^{
NSString *thumbnailURL = [NSString stringWithFormat:@"%@",deal_Class.deal_imageUrl];
image = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:@"Your URL"]];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageWithData:image];
if (image) {
[self.thumbnailsCache setObject:image forKey:thumbnailCacheKey];
}
});
});
// dispatch_release(imageQueue);
} else {
// thumbnail is in cache
NSData *image = [self.thumbnailsCache objectForKey:thumbnailCacheKey];
dispatch_async(dispatch_get_main_queue(), ^{
imageview.image = [UIImage imageWithData:image];
});
}
これには多くのチュートリアルが用意されています。
それらのいくつかを指摘しましょう:
UIScrollView を使用してコンテンツをスクロールおよびズームする方法
誰かのコード
DMLazyScrollView の使用に問題がない場合: UIScrollView の遅延読み込み (無限ページスクロール)
現在のページに加えて、いずれかの方向に 1 つまたは 2 つの画像のみをロードする必要があります。必要なときにのみ画像を読み込み、限られたバッファーを維持し、バッファーを離れた後に画像を削除します。たとえば、画像 3 と 4 が画面上にある場合、画像 1、2、5、および 6 をロードする必要があります。ユーザーが画像 5 と 6 が画面に表示されるようにスクロールすると、画像 3 と 4 が読み込まれたままになり、画像 1 と 2 がメモリから削除され、画像 7 と 8 が読み込まれて新しいバッファーが作成されます。