I have created the Custom tableView and using custom tableView class in Other class to Show the tableView..
I am Loading the image from Server and displaying it in the tableViewRow.. each image is different in it..
On Screen only 7 out of 10 images will come, and when I scroll down the first 3 images are repeating for some time and when those images get load its showing proper images.. but initially till new images will come its showing old images, I want to put a activity indicator to show that the images are loading instead of old images..
I want to add activity Indicator in the place of image, till the image get load..
My code is...
self.tableViewX = tableView;
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView1 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
NSString *imageURL = [NSString stringWithFormat: #"www.xyz.image.png"];
cell.thumbnailImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
});
Please assist me with some sample code..
You can use "AsyncImageView" class files it will load image synchronically and it shows the activity indicator while image loading
You can download "AsyncImageView" class files from following link:-
https://www.dropbox.com/s/peazwjvky9fsjd7/Archive.zip
in .m file import AsyncImageView Class
#import "AsyncImageView.h"
in your tableview cell at indexpath method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView1 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString *imageURL = [NSString stringWithFormat: #"www.xyz.image.png"];
AsyncImageView *async = [[AsyncImageView alloc]initWithFrame:CGRectMake(0, 0, width, height)];
[async loadImageFromURL:[NSURL URLWithString:imageURL]];
[cell.thumbnailImageView addSubview:async];
}
try this your problem will solve.
Related
I want to use activity indicator to show loading activity, like this:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Create cell
static NSString *cellIdentifier = #"cell";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyCellView" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// Check condition, either we got objects
if (!isDataLoaded){
cell.myActivityIndicator = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
cell.myActivityIndicator.center=self.view.center;
[cell.myActivityIndicator startAnimating];
[self.view addSubview:cell.myActivityIndicator];
NSLog(#"Current loading");
} else {
cell.myActivityIndicator.hidden = YES;
[cell.myActivityIndicator removeFromSuperview];
}
return cell;
}
However, its not vanish, even when i know that "else" block is executed. How to hide it?
I have implemented the CellForRowAtIndexPath method in my project that works.
It looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"StackTableViewCell";
Target *target = [self.fetchedResultController objectAtIndexPath:indexPath];
StackTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"StackTableViewCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
cell.cellLabel.text = target.body;
cell.cellLabel.font = [UIFont fontWithName:#"Candara-Bold" size:20];[UIFont fontWithName:#"Candara-Bold" size:20];
// Configure the cell...
return cell;
}
but there is something that bothers me and it's that I don't really understand what happened in this part (I took it from some tutorial):
if (!cell)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"StackTableViewCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
can someone please help me understand this?
thanks!
If the table view doesn't have a cell available to re-use, load the objects that exist in StackTableViewCell.xib. Assume that the first one you find that's defined at the top level can be instantiated as the type of cell that you want.
if (!cell)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"StackTableViewCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
You are trying to load cell from nib when cell is nil.
Usually, I do like this:
in ViewDidLoad
[self.tableView registerNib:[UINib nibWithNibName:#"StackTableViewCell" bundle:nil] forCellReuseIdentifier:cellIdentifier];
so in tableView:cellForRowAtIndexPath method you can get cell and you will not need to check if it nil or not, because it will always return cell
StackTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
I currently have an array with lots of image URLs called images They are being put into my table like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSLog(#"indexPath.row=%ld", (long)indexPath.row);
NSLog(#"images[indexPath.row]=%#", [images objectAtIndex:indexPath.row]);
NSString *stringy = #"http://www.tragicclothing.co.uk/";
NSString *link = [stringy stringByAppendingString: images[indexPath.row]];
NSString* encodedString = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:encodedString]];
cell.thumbnailImageView.image = [UIImage imageWithData: imageData];
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
cell.backgroundView = nil;
return cell;
}
But this is causing a lot of lag when scrolling. How could I cache the data? to prevent this lag? I have seen SDWebImage but I don't quite know how to use it! It seems very complicated.
Should I be using
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:#"myNamespace"];
[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image)
{
// image is not nil if image was found
}];
nothing can be simple then SDWebImage
it prodide the following solution
An UIImageView category adding web image and cache management to the Cocoa Touch framework
An asynchronous image downloader
An asynchronous memory + disk image caching with automatic cache expiration handling
#import <SDWebImage/UIImageView+WebCache.h>
NSString* encodedString = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[cell.thumbnailImageView setImageWithURL:[NSURL URLWithString:encodedString]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSLog(#"indexPath.row=%ld", (long)indexPath.row);
NSLog(#"images[indexPath.row + 7]=%#", [images objectAtIndex:indexPath.row + 7]);
NSString *stringy = #"http://www.tragicclothing.co.uk/";
NSString *link = [stringy stringByAppendingString: images[indexPath.row + 7]];
NSString* encodedString = [link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[cell.thumbnailImageView setImageWithURL:[NSURL URLWithString:encodedString] placeholderImage:[UIImage imageNamed:#"Comp 2_00000.png"]];
cell.backgroundColor = [UIColor clearColor];
cell.opaque = NO;
cell.backgroundView = nil;
return cell;
}
I am loading the image to the tableView, each time function
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
is executed, different url of image will come..
My problem is its taking so much time to load the image..
My code is..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
self.tableView1 = tableView;
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView1 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.nameLabel.text = title;
NSString *imageURL = [NSString stringWithFormat: #"http://www.xyz.com/image1.png];
cell.thumbnailImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:fullURL]]];
}
return cell;
}
every time the image url will change and it will take time to load each image..
can any one suggest any idea to solve this problem?
how multithreading will work with this code?
where and what should i edit in the code?
You have to download image in background like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView1 dequeueReusableCellWithIdentifier:simpleTableIdentifier];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString *u=[NSString stringWithContentsOfFile:r.url encoding:NSUTF8StringEncoding error:nil];
NSURL *imageURL=[NSURL URLWithString:u];
NSData *imageData=[NSData dataWithContentsOfURL:imageURL];
dispatch_sync(dispatch_get_main_queue(), ^{
SimpleTableCell *cell = (SimpleTableCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.thumbnailImageView.image=[UIImage imageWithData:imageData];
[cell setNeedsLayout];
});
});
}
return cell;
}
Just use above code in your table view method with required edit this should work for you.
You don't need multi threading. At least you don't need to do that on your own.
Have a look at this tutorial. It was very helpful for me when I started with Apps.
http://www.markj.net/iphone-asynchronous-table-image/
Alternatively subclass UIImageView and do this:
http://codeshape.wordpress.com/2011/05/10/creating-a-lazy-loading-uiimageview-for-ios/
Take a look at the SDWebImage framework:
SDWebImage Framework
Maybe it'll help you.
An alternative to Jeremy's answer which i have used before is the HJCache framework
Can just use the HJManagedImage object, it will download and cache the image asynchronously for you
I've got a problem with UIImage in the tableviewcell that are in storyboard.
When i scroll cell in the tableview it request the data from the server everytime so cell is very slow.
I've watched this video
but it does not work on storyboard, because storyboard donesn't have UITableViewCell NIB file (its integrate to the storyboard)
What I do in my project
I create object and link to my outlet property
I use json to get data from internet.
I display it on the tableview.
You can download my entire project file here. This is code in the UITableview.m cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
NSDictionary *entry = [ _entries objectAtIndex:indexPath.row];
cell.boomTitle.text = [entry objectForKey:#"body"];
NSString *imageURL=[NSString stringWithFormat:#"http://kelnakub.co.cc/upload/%i.jpg",[[entry objectForKey:#"IdEntry"] intValue]];
for(NSDictionary *dic in _entries)
{
NewsFeed *myNewsFeed = [[NewsFeed alloc]init];
myNewsFeed.thumNail = [dic objectForKey:#"IdEntry"];
}
NSURL *url = [NSURL URLWithString:imageURL];
NSData *imageData = [NSData dataWithContentsOfURL:url];
cell.boomImage.image = [UIImage imageWithData:imageData];
cell.boomDate.text = [entry objectForKey:#"dateCreated"];
return cell;
}
You can use UITableViewCell in a NIB file using storyboard. Just use prototype cells and, instead of designing the cell on the Storyboard, create a new NIB and design the UITableViewCell on it (Storyboard's UITableView remains empty of cells).
Then, in the code, you can load the cell using something like: UITableViewCell * MyCustomCell = [[[NSBundle mainBundle] loadNibNamed:#"MyCustomCell" owner:self options:nil] objectAtIndex:1];