Icon downloader downloads images only when UITableViewcell is outside screen.iPhone - ios

I tried searching but did not find any solutions helpful.
I am using the following code for icons lazy loading.
The issue is, the icons are downloaded via lazy loading, but they are only seen once that particular cell is out of screen and is scrolled back into the screen.
I think it is some issue with dequeueReusableCellWithIdentifier but am not sure how to resolve it.
The images are downloaded alright, but are only visible in the cell once the cell goes out of screen.
// -------------------------------------------------------------------------------
// tableView:cellForRowAtIndexPath:
// -------------------------------------------------------------------------------
- (UITableViewCell *)tableView:(UITableView *)tableVw cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// customize the appearance of table view cells
//
static NSString *CellIdentifier = #"LazyTableCell";
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell";
// add a placeholder cell while waiting on table data
NSUInteger nodeCount = [dataArray count];
if (nodeCount == 0 && indexPath.row == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.text = #"Loading…";
return cell;
}
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.backgroundColor = [UIColor grayColor];
// Leave cells empty if there's no data yet
if (nodeCount > 0)
{
// Set up the cell...
AppRecord *appRecord = [dataArray objectAtIndex:indexPath.row];
cell.textLabel.text = appRecord.appName;
cell.detailTextLabel.text = appRecord.artist;
// Only load cached images; defer new downloads until scrolling ends
if (!appRecord.appIcon)
{
if (tableView.dragging == NO && tableView.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
// if a download is deferred or in progress, return a placeholder image
cell.imageView.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
cell.imageView.image = appRecord.appIcon;
}
}
return cell;
}
- (void)startIconDownload:(AppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
IconDownloader *iconDownloader = [imageDownloadsInProgress objectForKey:indexPath];
if (iconDownloader == nil)
{
iconDownloader = [[IconDownloader alloc] init];
iconDownloader.appRecord = appRecord;
[iconDownloader setCompletionHandler:^{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// Display the newly loaded image
cell.imageView.image = appRecord.appIcon;
// Remove the IconDownloader from the in progress list.
// This will result in it being deallocated.
[imageDownloadsInProgress removeObjectForKey:indexPath];
}];
[imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
[iconDownloader startDownload];
}
}
- (void)loadImagesForOnscreenRows
{
if ([dataArray count] > 0)
{
NSArray *visiblePaths = [tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
AppRecord *appRecord = [dataArray objectAtIndex:indexPath.row];
if (!appRecord.appIcon)
// Avoid the app icon download if the app already has an icon
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self loadImagesForOnscreenRows];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
}

I did code like following,
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:aURL
options:0
progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
{
if (image)
[aCell.imgViewThumb setImage:image];
else
[aCell.imgViewThumb setImage:[UIImage imageNamed:#"Dummy-image.jpg"]];
[aCell.indicator stopAnimating];
}];

Related

Stop reloading UItableView again and again in Iphone

I am working on a chat app,In that i have used UITableView for chatting screen. In every chat bubble user's profile pic is there,Now my issue is when a new message come or i am sending new message whole tableView is reloading with images in chat bubble also, I want to stop it,Can anybody help me to figure it out?
my code is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.chatTableView)
{
NSString *cellID;
if([[((UUMessageFrame *)(self.chatModel.dataSource[indexPath.row])) message] from] == UUMessageFromMe)
{
cellID = #"outgoing_cell";
}
else
{
cellID = #"incoming_cell";
}
//commented by jigar
// UUMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// UUMessageCell *cell = [tableView];
UUMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[UUMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
cell.delegate = self;
if ([cellID isEqualToString:#"outgoing_cell"])
{
// cell.recognizer.numberOfTapsRequired
[cell.recognizer addTarget:self action:#selector(longPress:)];
}
}
[cell setMessageFrame:self.chatModel.dataSource[indexPath.row]];
NSLog(#" text message is : %#",[cell.btnContent titleForState:UIControlStateNormal]);
cell.btnContent.tag = indexPath.row;
return cell;
}
else
{
NSString *cellIdentifier;/* = isOutgoingMessage ? self.outgoingCellIdentifier : self.incomingCellIdentifier;*/
if ([[self.arrTableData objectAtIndex:indexPath.row] isKindOfClass:[OTRVoice class]])
{
OTRVoice *voice = (OTRVoice *)[self.arrTableData objectAtIndex:indexPath.row];
if(![voice.fk_Tripper isEqualToString:appDelegate.account.uniqueId])
{
cellIdentifier = self.incomingCellIdentifier;
}
else
{
cellIdentifier = self.outgoingCellIdentifier;
}
}
else{
cellIdentifier = self.outgoingCellIdentifier;
}
#try
{
VoiceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
cell.avatarImage.clipsToBounds = YES;
cell.avatarImage.layer.cornerRadius = cell.avatarImage.bounds.size.width / 2.0;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
tableview.separatorStyle = UITableViewCellSeparatorStyleNone;
cell.circular_ProgressView.frame = CGRectMake(cell.btnPlay.frame.origin.x-2, cell.btnPlay.frame.origin.y, 26, 26);
[self configureCell:cell atIndexPath:indexPath];
cell.tag = indexPath.row +10000;
return cell;
}
#catch(NSException *e)
{
NSLog(#"Exception is : %#",e);
}
}
}
you can use https://github.com/rs/SDWebImage library.
In this lib you can set the image directly to UIImageview using lazy loading concept. So even if you set image every time. it will not download again and again.
check the below code for example.
NSURL *url = [NSURL URLWithString:#"url"];
[cell.avatarImage setImageWithURL:url usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

Uitableview scroll lag With Lazyloading(apple Source Code)

Im trying to figure out why my program runs well on simulator but not on Phone.
when i scroll my Tables it gets laggy.
ive tried everything , even removed my Images loading but still scroll lag happen.
Im using apple lazy loading source code :
this is my code :
#define kCustomRowCount 7
#interface SubCategoryViewController () <UIScrollViewDelegate>
#property (nonatomic, strong) NSMutableDictionary *imageDownloadsInProgress;
#property (nonatomic, strong) NSMutableDictionary *imageRestitleDownloadsInProgress;
#property (nonatomic, assign) int intindex;
#end
#implementation SubCategoryViewController
#pragma mark
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = self.catname;
self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
self.imageRestitleDownloadsInProgress = [NSMutableDictionary dictionary];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
NSArray *allDownloads = [self.imageDownloadsInProgress allValues];
[allDownloads makeObjectsPerformSelector:#selector(cancelDownload)];
NSArray *allDownloads2 = [self.imageRestitleDownloadsInProgress allValues];
[allDownloads2 makeObjectsPerformSelector:#selector(cancelDownload)];
[self.imageDownloadsInProgress removeAllObjects];
[self.imageRestitleDownloadsInProgress removeAllObjects];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSUInteger count = [self.entries count];
// if there's no data yet, return enough rows to fill the screen
if (count == 0)
{
return kCustomRowCount;
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell2";
NSUInteger nodeCount = [self.entries count];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
cell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
UILabel *newsbody = (UILabel *)[cell.contentView viewWithTag:6];
UIImageView *uimg = (UIImageView *)[cell.contentView viewWithTag:20];
UIImageView *uimgresttile = (UIImageView *)[cell.contentView viewWithTag:23];
if (nodeCount == 0 && indexPath.row == 0)
{
if (cell == nil) {
uimg.hidden = true;
uimgresttile.hidden = true;
newsbody.hidden = true;
}
else
{
uimg.hidden = true;
uimgresttile.hidden = true;
newsbody.hidden = true;
}
return cell;
}
if (nodeCount == 0 && indexPath.row > 0)
{
cell.hidden = true;
return cell;
}
if (nodeCount > 0)
{
uimg.hidden = false;
uimgresttile.hidden = false;
newsbody.hidden = true;
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
[newsbody setText:appRecord.Body];
if (!appRecord.appIcon)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
uimg.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
uimg.image = appRecord.appIcon;
}
if (!appRecord.appIconrestitle)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
[self startRestitleIconDownload:appRecord forIndexPath:indexPath];
}
uimgresttile.image = [UIImage imageNamed:#"Placeholder.png"];
}
else
{
uimgresttile.image = appRecord.appIconrestitle;
}
}
if ((unsigned long)indexPath.row == [self.entries count] - 1){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
^{
NewsFetchParseOperation *p = [[NewsFetchParseOperation alloc]init];
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
p.cat = appRecord.Category;
self.intindex = self.intindex + 1;
p.index = [NSString stringWithFormat:#"%d", (int)self.intindex];
p.lastid = appRecord.ids;
[p main];
dispatch_async(dispatch_get_main_queue(), ^(void)
{
SubCategoryViewController *svc =[self.storyboard instantiateViewControllerWithIdentifier:#"SubCategory"];
NSArray *temp =[self.entries arrayByAddingObjectsFromArray:p.appRecordList];
self.entries = temp;
[self.tableView reloadData];
});
});
}
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *PlaceholderCellIdentifier = #"PlaceholderCell2";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
height += 1;
return height;
}
- (void)startIconDownload:(NewsFetchAppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
NewsFetchIconDownloader *iconDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
if (iconDownloader == nil)
{
iconDownloader = [[NewsFetchIconDownloader alloc] init];
iconDownloader.newsfetchappRecord = appRecord;
[iconDownloader setCompletionHandler:^{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIImageView *uimg = (UIImageView *)[cell.contentView viewWithTag:20];
uimg.image = appRecord.appIcon;
[self.imageDownloadsInProgress removeObjectForKey:indexPath];
}];
[self.imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
[iconDownloader startDownload];
}
}
- (void)startRestitleIconDownload:(NewsFetchAppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
NewsFetchRestitleIconDownloader *ResttitleiconDownloader = [self.imageRestitleDownloadsInProgress objectForKey:indexPath];
if (ResttitleiconDownloader == nil)
{
ResttitleiconDownloader = [[NewsFetchRestitleIconDownloader alloc] init];
ResttitleiconDownloader.newsfetchappRecord = appRecord;
[ResttitleiconDownloader setCompletionHandler:^{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIImageView *uimgresttile = (UIImageView *)[cell.contentView viewWithTag:23];
uimgresttile.image = appRecord.appIconrestitle;
[self.imageRestitleDownloadsInProgress removeObjectForKey:indexPath];
}];
[self.imageRestitleDownloadsInProgress setObject:ResttitleiconDownloader forKey:indexPath];
[ResttitleiconDownloader startDownload];
}
}
- (void)loadImagesForOnscreenRows
{
if ([self.entries count] > 0)
{
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
if (!appRecord.appIcon)
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
- (void)loadRestitleImagesForOnscreenRows
{
if ([self.entries count] > 0)
{
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
if (!appRecord.appIconrestitle)
{
[self startRestitleIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self loadImagesForOnscreenRows];
[self loadRestitleImagesForOnscreenRows];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
[self loadRestitleImagesForOnscreenRows];
}
#end
Edit:
In iphone if i scroll the the table it will freeze and jump most of time. even when
picture loaded properly. this problem never happen in simulator and only in real device.
i read most of article here base on "uitableview" lagging. most them suggest to use asnyc
method for downloading images. im using apple lazyloading sample method so i guess images
gets downloaded other than main thread.
think i have done till now is to comment most of code section by section and still lag
happend.
i even remove most part from Storyboard , but still lag happend.
You should delete all of your image download methods. Delete also scrollViewDidEndDragging and scrollViewDidEndDecelerating. I don't know why your heightForRowAtIndexPath is so complicated. Is every row a different size? If not use a simple case statement with the couple of cases you've got. Different height for each row can be a drag on resources.
Now for cellForRowAtIndexPath:
If the hidden not hidden stuff you are doing is for performance you should delete all of that.
Add AFNetworking to your project. If you are using cocaopods (you should) can add it with on line in your Podfile. It's good practice when developing with iOS to use libraries and AFNetworking is the best when it comes to getting stuff like images from a network.
#import "UIImageView+AFNetworking.h"
Now all your image work is done with one line of code (AFNetworking will handle all the caching and the performance related issues and the asynchronous stuff for you):
[uimg setImageWithURL:"http://blahbahblah.com" placeholderImage:someUIIMage]

Using AFNetworking to update a UITableViewCell once a download is complete

Within our app we have a free magazine that users can download in PDF format. If they have not downloaded an issue, that UITableViewCell image has a low alpha so that the user can see that it is not downloaded.
If you tap a cell it will start to download using an AFHTTPRequestOperation and once complete you can view the PDF using QuickLook.
The problem I am having is, when the user initiates the download, then scrolls away and then back, the UITableViewCell that they tapped somehow loses reference that it was downloading and therefore doesn't update the UIProgressView or change the alpha to 1.0 when the download is finished. I cannot for the life of me figure out why [[tableView indexPathForCell:cell] isEqual:indexPath] is not equaling:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PUCViewpointItem *item = [self.items objectAtIndex:indexPath.row];
// Check to see if we are already on the row that is activated
if (indexPath.row == self.selectedIndexPath.row) {
// File Path
NSString *path = [self itemPath:item];
// Should we read the issue
if (item.isDownloaded && path) {
item.downloadPath = path;
[self readIssue:item];
return;
}
// TableView Cell
PUCViewpointTableViewCell *cell = (PUCViewpointTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if (!path) {
Utility *utility = [[Utility alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:item.url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *localPath = [[utility localDirectory] stringByAppendingFormat:#"/%#.pdf", item.name];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:localPath append:NO];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float totalProgress = (float)totalBytesRead/totalBytesExpectedToRead;
if ([[tableView indexPathForCell:cell] isEqual:indexPath]) {
cell.progressView.hidden = NO;
cell.progressView.progress = totalProgress;
item.isDownloading = YES;
item.isDownloaded = NO;
item.progress = totalProgress;
}
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([[tableView indexPathForCell:cell] isEqual:indexPath]) {
cell.fullImage.alpha = 1.0f;
cell.progressView.hidden = YES;
item.isDownloaded = YES;
item.isDownloading = NO;
}
NSLog(#"%d == %d", [tableView indexPathForCell:cell].row, indexPath.row);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if ([[tableView indexPathForCell:cell] isEqual:indexPath]) {
cell.progressView.hidden = YES;
item.isDownloading = NO;
item.isDownloaded = NO;
}
}];
[operation start];
}
return;
}
NSIndexPath *oldIndexPath = self.selectedIndexPath;
self.selectedIndexPath = indexPath;
[tableView beginUpdates];
[tableView endUpdates];
// Which way are we scrolling?
UITableViewScrollPosition position;
if (indexPath.row == 0 || (oldIndexPath && oldIndexPath.row < indexPath.row)) {
position = UITableViewScrollPositionTop;
} else {
position = UITableViewScrollPositionBottom;
}
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:position animated:YES];
}
If I start a download, then scroll down in my tableView, my NSLog statement will log something like 3 == 10 which makes no sense.
Any ideas how I can fix this?
I was curious about your case so I wrote a little test project, you can find it here: https://github.com/mrojas/MRTableViewTest
Basically, the way to solve it was:
Put the logic to download an item, in the item class
Make the cell be the delegate of the item, to be notified about progress/completion
When cells are scrolled (reused), setting the item on them is enough. They figure the current status and set themselves to be delegates.
Check the project, try it, and let me know if you have doubts.
I didn't use AFNetworking but instead simulated some task that takes 10 seconds to complete, in 2 seconds interval.
I think you have to store somewhere (like an NSMutableArray instance variable) the indexPath you are downloading. so you can do something like that :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if( [indexArray indexOfObject:indexPath] != NSNotFound )
{
// alpha for downloading
}
}
In your AFNetworking completion blocks you should remove this indexPath from you indexArray.
As comments said, cells are not reliable for storing any kind of information as they are reallocated when you scroll
#interface ViewController ()
{
NSMutableArray *_indexArray;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITableView *table = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
table.delegate = self;
table.dataSource = self;
_indexArray = [#[] mutableCopy];
[self.view addSubview:table];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return 50;
}
// called when you scroll to new cells or when reloadData is called
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"default"];
cell.textLabel.textColor = [UIColor blueColor];
// red color if I'm downloading, else blue
if ([_indexArray indexOfObject:indexPath] != NSNotFound) {
cell.textLabel.textColor = [UIColor redColor];
}
cell.textLabel.text = #"cell in the table";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
[_indexArray addObject:[indexPath copy]];
NSLog(#"downloading...");
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.textColor = [UIColor redColor]; // update UI temporary (until scroll)
// HD Image so I can scroll up and down for testing
NSString *res = #"http://res.cloudinary.com/******/image/upload/*****/Motorola_Razr_HD_Cam_Sample_7_ftzrj0.jpg";
// custom class for download
[[PLSApi api] downloadDataAtURL:[NSURL URLWithString:res] withBlock:^(NSData *data) {
// download complete
[_indexArray removeObject:indexPath];
cell.textLabel.textColor = [UIColor blueColor]; // update UI
NSLog(#"finished...");
}];
}

Application crashing with Exc_Bad_Thread iPhone

I am trying to implement https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html
code for collection view.. Everything is working fine. But in cellForRowAtIndex method while re-loading of old cell the application is crashing. Have a look at code:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:
(NSInteger)section
{
if (self.galleryItemsArray) {
return [self.galleryItemsArray count];
}
else
{
return 0;
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger nodeCount = [self.galleryItemsArray count];
static NSString* simpleTableIdentifier = #"SavedMessageCell_ID";
SavedMessagesCell *cell = [cv dequeueReusableCellWithReuseIdentifier:simpleTableIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[SavedMessagesCell alloc] initWithFrame:CGRectZero];
}
cell.textLabel.text = [NSString stringWithFormat:#"{%ld,%ld}", (long)indexPath.row, (long)indexPath.section];
if(nodeCount>0)
{
GalleryItemDS *item = [self.galleryItemsArray objectAtIndex:indexPath.row];
// Only load cached images; defer new downloads until scrolling ends
if (!item.imageOfItem)
{
if (gallery_collectionView.dragging == NO && gallery_collectionView.decelerating == NO)
{
[self startIconDownload:item forIndexPath:indexPath];
NSLog(#"%#",item.PhotoPath);
}
// if a download is deferred or in progress, return a placeholder image
cell.image.image = [UIImage imageNamed:#"Icon.png"];
}
else
{
NSLog(#"%#",[NSString stringWithFormat:#"{%ld,%ld}", (long)indexPath.row, (long)indexPath.section]);
NSLog(#"%#",item.PhotoPath);
**cell.image.image = item.imageOfItem; // Crashing here**
}
}
return cell;
}
// -------------------------------------------------------------------------------
// startIconDownload:forIndexPath:
// -------------------------------------------------------------------------------
- (void)startIconDownload:(GalleryItemDS *)galleryItem forIndexPath:(NSIndexPath *)indexPath
{
IconDownloader *iconDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];
if (iconDownloader == nil)
{
iconDownloader = [[IconDownloader alloc] init];
iconDownloader.galleryItem = galleryItem;
[iconDownloader setCompletionHandler:^{
SavedMessagesCell *cell = (SavedMessagesCell *)[gallery_collectionView cellForItemAtIndexPath:indexPath];
// Display the newly loaded image
cell.image.image = galleryItem.imageOfItem;
// cell.backgroundColor = [UIColor colorWithPatternImage:galleryItem.imageOfItem];
// Remove the IconDownloader from the in progress list.
// This will result in it being deallocated.
[self.imageDownloadsInProgress removeObjectForKey:indexPath];
}];
[self.imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
[iconDownloader startDownload];
}
}
- (void)loadImagesForOnscreenRows
{
if ([self.galleryItemsArray count] > 0)
{
NSArray *visiblePaths = [gallery_collectionView indexPathsForVisibleItems];
for (NSIndexPath *indexPath in visiblePaths)
{
GalleryItemDS *appRecord = [self.galleryItemsArray objectAtIndex:indexPath.row];
if (!appRecord.imageOfItem)
// Avoid the app icon download if the app already has an icon
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
#pragma mark - UIScrollViewDelegate
// -------------------------------------------------------------------------------
// scrollViewDidEndDragging:willDecelerate:
// Load images for all onscreen rows when scrolling is finished.
// -------------------------------------------------------------------------------
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self loadImagesForOnscreenRows];
}
}
// -------------------------------------------------------------------------------
// scrollViewDidEndDecelerating:
// -------------------------------------------------------------------------------
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnscreenRows];
}
Please help me in it.

How can I solve this delegate error?

I have a delegate, but it doesn't work without the other delegate line in it:
- (id)initWithData:(NSData *)data delegate:(id <ParseOperationDelegate>)theDelegate {
self = [super init];
if (self != nil) {
self.dataToParse = data;
self.delegate = theDelegate;
}
appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
It should load data in a Cell but the data isn't shown before the first scroll. What can I do?
EDIT:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"productCell";
static NSString *PlaceholderCellIdentifier = #"placeholderCell";
int nodeCount = [appDelegate.products count];
if (nodeCount == 0 && indexPath.row == 0) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PlaceholderCellIdentifier];
cell.detailTextLabel.textAlignment = UITextAlignmentCenter;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.detailTextLabel.text = #"Loading...";
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (nodeCount > 0) {
XMLProductView *listedProduct = [appDelegate.products objectAtIndex:indexPath.row];
cell.textLabel.text = listedProduct.name;
// cell.detailTextLabel.text = appRecord.artist;
if (!listedProduct.productImage) {
if (self.tableView.dragging == NO && self.tableView.decelerating == NO) {
[self startImageDownload:listedProduct forIndexPath:indexPath];
}
UIImageView *listedImage = (UIImageView *)[cell viewWithTag:1];
listedImage.image = [UIImage imageNamed:#"Placeholder.png"];
}
else {
UIImageView *listedImage = (UIImageView *)[cell viewWithTag:1];
listedImage.image = listedProduct.productImage;
}
}
return cell;
}
your code seems that its waiting for some event, or some files to get fetched or downloaded, so you will need to call [tableview reloadData]; when this data is downloaded,
I cant figure it out from the code, but my guts tells me this
1st:
that you are waiting for data from int nodeCount = [appDelegate.products count]; to be ready, so you will need to have some sort of delegate that gets called when this data is ready
2nd:
you are waiting for an image to get downloaded here [self startImageDownload:listedProduct forIndexPath:indexPath], so when this actually get downloaded you will need to set the image to that cell or reloadData on the table
That is what i can figure out from the code.

Resources