scheint so, als gäbe es zwei Themen ist hier:
Das erste Problem mit ist:
cellForItemAtIndexPath
jedes einzelne Mal, wenn die Zelle erscheint auf dem Bildschirm aufgerufen wird, was bedeutet, wenn Sie scrollen dann wird downloadImageWithURL
jedes mal aufgerufen, wenn eine Zelle auf dem Bildschirm erscheint.
Das zweite Problem scheint mit for (int i=0; i<=[[item objectForKey:@"Count"]integerValue]; i++)
Diese Schleife mehrere Bilder und sie dann auf der gleichen Zelle wiederum setzt zum Download scheint für jede Zelle, die mehrere Bilder werden geladen werden?
Einige Lösungen zur ersten Ausgabe:
- Wenn Sie müssen nur ein paar Elemente anzuzeigen, laden Sie alle Bilder in
viewDidLoad
und aktualisieren Sie die Datenquelle jedes Mal eines der Bilder heruntergeladen hat.
- Nachdem das Bild für jede Zelle heruntergeladen wurde, fügen Sie es zu einem Array hinzu. Jedes Mal, wenn eine Zelle geladen wird, prüfen Sie, ob das Array ein Image für diese Zelle enthält und verwenden Sie dieses, anstatt ein neues herunterzuladen.
Um das zweite Problem:
Unsicher, was die Schleife hier zu erreichen, gemeint ist, wollen Sie jedes Bild aus der Schleife in einer eigenen Sammlung Ansicht Zelle angezeigt werden?
Aktualisiert:
Hier ein kurzes Beispiel ist, Ihnen zu zeigen, wie der Code aussehen könnte.Ich habe keine Ahnung, was in jsonSD
oder einige der anderen Teile des Codes enthalten ist, aber es sollte Ihnen die richtige Idee geben:
@interface TestCollectionViewController() {
NSMutableArray *datasource;
NSDictionary *jsonSD;
}
@end
@implementation TestCollectionViewController
static NSString *const reuseIdentifier = @"Cell";
- (void)viewDidLoad {
[super viewDidLoad];
// We want to load the data from all cells as soon as the view loads, instead of loading the data as the cells scroll.
// Lazy loading cells will require a more advanced implementation
[self loadDatasource];
}
- (void)loadDatasource {
for (NSDictionary *item in [jsonSD objectForKey:@"Data"]) {
// Fill the datasource with null objects which match the total number of objects you want to display
datasource = [NSMutableArray arrayWithCapacity:[[item objectForKey:@"Count"] integerValue]];
for (int i = 0; i <= [[item objectForKey:@"Count"] integerValue]; i++) {
[datasource addObject:[NSNull null]];
}
// Reload the collectionview now so that the empty cells will be displayed with no image.
[self.collectionView reloadData];
// Load each image individually and replace the corresponding NSNull in the datasource.
for (int i = 0; i <= [[item objectForKey:@"Count"] integerValue]; i++) {
NSString *filename = [NSString stringWithFormat:@"http://..URL../media/content/%@%@%d_1.png", _getstring, [item objectForKey:@"subcategory_id"], i];
NSURL *url = [NSURL URLWithString:filename];
[self downloadImageWithURL:url completionBlock:^(BOOL succeeded, NSData *data) {
if (succeeded) {
[datasource replaceObjectAtIndex:i withObject:[UIImage imageWithData:data]];
// Reload the collectionview after each item has downloaded so the image gets displayed in the cell.
[self.collectionView reloadData];
}
}];
}
}
}
- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, NSData *data))completionBlock {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
completionBlock(YES, data);
} else {
completionBlock(NO, nil);
}
}];
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
// Only displaying one section
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return datasource.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
if ([datasource objectAtIndex:indexPath.row] == [NSNull null]) {
// Display a default image here
} else {
// Image has been loaded, display it in the imageview
iv.image = [datasource objectAtIndex:indexPath.row];
}
return cell;
}
Update 2:
Die Antwort oben ist nicht schrecklich effizient und wird nicht gut funktionieren, wenn Sie Hunderte von Artikeln haben. Für eine solidere Implementierung würde ich empfehlen, eine Bibliothek wie SDWebImage zu verwenden, um es für Sie zu handhaben. Dann können Sie etwas so einfaches tun wie:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {... completion code here ...}];
Sie haben es richtig erkannt. Ich möchte nicht alle Bilder in einer einzelnen Zelle anzeigen. Ich möchte ein einzelnes Bild für eine einzelne Zelle. – ammy1
könntest du mir bitte helfen. – ammy1
@ Greg- danke für den Vorschlag. Ich werde es versuchen. – ammy1