Im trying to load a single image into the grouped table cell. I found a piece of code on the internet and modified it. Original code is using UIViews to display image, which is not what I need, however original code works of course. PLease help me to make this code work to display an image in a sigle cell for grouped tableview. My TableView has only one row and it has UITableViewCellStyleDefault style.
Original Code
Here is my modified method, this is the core method.
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection
{
[connection release];
connection=nil;
UIImage *img = [UIImage imageWithData:data];
self.image = img;
self.frame = self.bounds;
[self setNeedsLayout];
[data release];
data=nil;
}
This is how I use it to display image in my TableView Cell cellForRowAtIndexPath method.
CGRect frame;
frame.size.width=75; frame.size.height=75;
frame.origin.x=0; frame.origin.y=0;
AsyncImageView* asyncImage = [[[AsyncImageView alloc] initWithFrame:frame] autorelease];
[asyncImage loadImageFromURL:imageURL];
cell.imageView.image = asyncImage.image;
In that code you posted, the image of the AsyncImageView doesn't get set until after the connection finishes loading and it actually creates the image. Problem is, you're setting it's image into the cell immediately. That's not going to work!
You're going to want to make a custom cell class (subclass UITableViewCell) and use that cell in your table. There's lots of sample code showing how to use custom cells and lay them out with views. Instead of using UITableViewCell's standard imageView, create your own layout and use an AsyncImageView to show your image. Then it should work.
Related
I have a Tableview containing cells with images, however the cells that are reused still contain the image from the previous cell that is being reused until the new image is downloaded and set.
I have tried setting the image to nil. (imageV is a subclass of HJManagedImageV, source can be found here: HJManagedImageV
[cell.imageV setImage:nil];
the setter
-(void)setImage:(UIImage *)theImage{
if (theImage==image) {
//when the same image is on the screen multiple times, an image that is alredy set might be set again with the same image.
return;
}
[theImage retain];
[image release];
image = theImage;
[imageView removeFromSuperview];
self.imageView = [[[UIImageView alloc] initWithImage:theImage] autorelease];
[self addSubview:imageView];
[imageView setNeedsLayout];
[self setNeedsLayout];
[loadingWheel stopAnimating];
[loadingWheel removeFromSuperview];
self.loadingWheel = nil;
self.hidden=NO;
if (image!=nil) {
[callbackOnSetImage managedImageSet:self];
}
}
I have a workaround for by setting imageV to hidden but then I lose the loading spinner and I'd really like to know why setting it to nil isn't working.
Anyone have any ideas, cause I'm all out of them. Or am I missing a step somewhere.
Are the cells a subclass of UITableViewCell? If yes, I would try to implement the method prepareForReuse and see if can solve the problem there.
Hope this helps =)
Don't set it to nil, nor hide it.
We use a similar class and what we do for such cases is to set a start image to be displayed until the new image loads.
So in your case you could simply set the image as a blank jpg/png inside your bundle instead of nil
I have an asychronous image loader which loads images (JImage) in a UIImageview. I want to display these in a tablecell. Obviously i cant set cell.imageView.image because i dont have an image, i just have a view.
How do i set the UIImageview to the tablecell? cell.backgroundView works though, but that paints over the whole cell.
The JImage code is:
NSURL *theUrl=[NSURL URLWithString:imageURL];
JImage *photoImage=[[JImage alloc] init];
[photoImage initWithImageAtURL:theUrl];
[photoImage setContentMode:UIViewContentModeRedraw];
[photoImage setFrame:CGRectMake(0.0f, 0.0f, 40.0f, 65.0f)];
cell.backgroundView = photoImage;
[photoImage release];
which in the JImage.m:
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection
{
[self setImage:[UIImage imageWithData: data]];
}
use this code and set frame according to your need.
UIImage *imagearrow = [UIImage imageNamed:#"arrow.png"];
UIImageView *imgarrow=[[UIImageView alloc] initWithFrame:CGRectMake(290, 25, 7, 15)];
imgarrow.image =imagearrow;
[cell addSubview:imgarrow];
[imagearrow release];
You don't need to use JImage if all you want to do is load the image asynchronously. One easy way to do this is with GCD and blocks, like so: https://github.com/ChrisTec/iPhone-Book-CodeSamples/blob/master/Chapter%2013/RealEstateViewer%2013.2.5/RealEstateViewer/ImageTableViewController.m
Here's a sample chapter of the book Objective-C Fundamentals which I've co-authored that explains this code in depth: http://www.manning.com/fairbairn/OCF_sample_ch13.pdf
To sum it up: When the cell is requested, you look if you already have downloaded the image. If you have, you display it. If not, you display a spinner and start an async GCD block that will fetch the image. One that block is done, it will run another block on the main thread that switches the spinner out for the image. That's all.
I think you should take a different approach to this. Instead of putting your JImage in the cell, hold it somewhere else in the view controller, an NSArray is usually convenient. Then populate the cells with either placeholder images or just leave them empty.
So let's say you have an array with all the JImages that are loading, when the JImage in the position x of the array finishes loading, you reload that specific cell as it follows:
NSIndexPath indexPath = [NSIndexPath indexPathForRow:x inSection:0];
[self.tableView reloadRowsAtIndexPaths:x withRowAnimation:NO];
And in your cellForRow:AtIndexPath you just have to take the image from the JImage object held in the array.
I hope this helps you
Why should we avoid loading a image from server while drawing a cell?
In my app I get data from server which contains image URLs as well. Now, I draw my cells and use these image URLs to fetch image from the server and draw it. Now, sometimes image does not get displayed even if image is actually present at that URL as I can see it through browser.
Is there any cell drawing limitation which could cause this issue? Shall I fetch images when I get data from server.
Does cell rendering happens before image is actually drawn.
NSString *imgUrl = [ImageURLArray objectAtIndex:indexPath.row];
if(imgUrl != nil)
{
NSString * ImagePath;
NetworkManager *manager = [[NetworkManager alloc] init];
ImagePath = [manager GetFile:imgUrl];
[manager release];
manager = nil;
if(ImagePath != nil)
{
UIImage *newImage = [UIImage imageWithData:[NSData dataWithContentsOfFile:ImagePath]];
UIGraphicsBeginImageContext(CGSizeMake(50, 50));
// now redraw our image in a smaller rectangle.
[newImage drawInRect:CGRectMake(25, 10, 30, 30)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.imageView.image = newImage;
}
}
return cell;
}
hope this will solve your problem
What could be happening is you have a main thread which is the UI display thread. By fetching image from a url from this thread, you are essentially blocking the cell (i.e. scrolling). Also might be the case that the image is in the process of downloading in which case you'll not see it till it downloads.
Generally UITableView does not display the cell till it's ready to be displayed, by doing the image download in the main thread you are harming your performance. What you should do is to launch a background thread which downloads the image from the url & then update the cell of the image contents when the download is ready.
Best way is to have an initial placeholder like a default image or a spinner, which gets replaced when the main image download gets done.
Dont worry you dont need to implement all this. No point in reinventing the wheel. Here's an awesome library which I use for the same - UIImageView + WebCache
fetch images when I you data from server and pass the information to the view.
like
ImageView *imageView = [[ImageView alloc] initWithNibName:#"ImageView" bundle:[NSBundle mainBundle]];
imageView.prod=self.prod;
imageView.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:imageView animated:YES];
[imageView release];
imageView=nil;
hope this will solve your problem
Clearly, the image download is taking more time. You should be using placeholder images until the download completes. You can't stop the user from scrolling.
I have set imageView's frame in table using the following code.
cell.imageView.image = [UIImage imageWithContentsOfFile:[[users objectAtIndex:indexPath.row] valueForKey:#"ImagePath"]];
[cell.imageView setFrame:CGRectMake(5, 5, 10, 10)];
But image is displayed from the corner of the cell.
It does not changes the position or size.
what should I do ?
You will not be able to change the cells imageView frame. Your best option would be to create a custom cell.
You can change the frame of the cell by creating a subclass of UITableViewCell and overriding the layoutSubviews method.
In your subclass implementation of layoutSubviews, call super's implementation first and then modify the frame of imageView.
You can add your desired imageview as a subview to the cell
UIImageView *imageView = [[UIImageView alloc] init];
imageView.image = [UIImage imageWithContentsOfFile:[[users objectAtIndex:indexPath.row] valueForKey:#"ImagePath"]];
[imageView setFrame:CGRectMake(5, 5, 10, 10)];
[cell addSubview:imageView];
You can create custom table view cells and position the elements where you want them to be.
Its also helpful as you will have control on how similar you want your UI to be be to the requirements.
You can do it in interface builder or in code. Also there are loads of examples as this is most common approach in iphone app development (Having a custom table view cell) and you can use the delegates to populate the table view and it works like a charm.
In my application,i created an imageview on the above the tabbar.I want to display some images here for displaying some adds there.
What my actual problem is...i added this on my table view and whenever i am scrolling the table view ,my imageview is also scrolling.Please help me in this
Thanks in advance.Here is my code
UIImageView *currentLocationImageView = [[UIImageView alloc] init];
NSURL *url1 = [NSURL URLWithString:#"http://imgsrv.995themountain.com/image/kqmt2/UserFiles/Image/SiteGraphics/MTNVideos360x80.jpg"];
UIImage *img1 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url1]];
NSURL *url2 = [NSURL URLWithString:#"http://download.xbox.com/content/images/35f6c527-fb73-40d3-bcb9-bdea2680bc03/1033/banner.png"];
UIImage *img2 = [UIImage imageWithData: [NSData dataWithContentsOfURL:url2]];
NSArray *images = [NSArray arrayWithObjects:img1, img2, nil];
[currentLocationImageView setAnimationImages:images];
[currentLocationImageView setAnimationRepeatCount:0];
[currentLocationImageView setAnimationDuration:5.0];
currentLocationImageView.frame = CGRectMake(0.0, 340.0, 320.0, 30.0);
//self.tableView.tableFooterView = currentLocationImageView;
[currentLocationImageView startAnimating];
[self.view addSubview:currentLocationImageView];
Without seeing more code, it looks as though you may be using a UITableViewController instead of a UIViewController. The difference between the two is important in the case of your last line [self.view addSubview:currentLocationImageView]. What that does in a UIViewController is adds it to the view that would be containing the tableview and the imageview. However, in a UITableViewController the self.view property holds the tableview itself, therefor, it ads your image view as a subview of the tableview, subjecting it to the tableview's scrolling behaviour.
What you can do is change from using a UITableViewController (probably going to be trivial for your application, but may be less than trivial depending on why you opted to use it in the first place); and you'll also need to explicitly create the tableview, and add it to the backing view of the UIViewController subclass you're writing—akin to how you're adding the imageview above.
Hope this helps.