How to add image in tableview in iphone - iphone

I have to add image in tableview in each. I have 2 list one is for twitter and second is for facebook. I want to show each list with their image icon. here is my code to attach value in table of twitter.
for (NSDictionary *wallText in sortedarray) {
NSString *wallNameValue = [wallText objectForKey:#"message"];
if(![[NSNull null] isEqual:wallNameValue] && [wallNameValue length])
{
[tableList addObject:wallNameValue];
}
}
I want to show twitter image in left of row. How will i add image.
Thanks in advance

Just try using in this Way:
cell.imageView.image = [UIImage imagedNamed:[wallText objectForKey:#"message"]];
& plus there is no need to run any loop for this.This is optimize your code.
Just access the array via indexpath.row
NSDictionary *wallText = (NSDictionary *)[[sortedarray objectAtIndex:indexPath.row]valueForKey:message];
Hope you are going to do all these things in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath .

In your table view's delegate, in the method that sets up your UITableViewCell's, do something like this:
cell.imageView.image = myImage;
// myImage is a UIImage *.
Every UITableViewCell comes with a UIImageView built in that displays an image for you on the left side of the cell.
Reference:
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UITableViewCell_Class/Reference/Reference.html

In cellForRowAtIndexPath just do
cell.imageView.image = [UIImage imageWithData:[yourImageDataArray objectAtIndex:indexPath.row]];

Related

Photo album appearing in the wrong order in uicollectionview

I am using a library called psuicollection view cell to post some picture in a cell. It works great except for one crucial flaw. It doesn't post them in the right order, the exact opposite order to be exact. If I were to post picture A then picture B, picture B will be the first picture then picture A would be the next photo. How Do I reverse the image's order?
- (PSUICollectionViewCell *)collectionView:(PSUICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
PhotosModel *photoModel = [self.Photos objectAtIndex:indexPath.row];
Cell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:GridCellIdentifier forIndexPath:indexPath];
cell.image.clipsToBounds=YES;
[cell.image setContentMode:UIViewContentModeScaleAspectFill];
[cell.image setImageWithURL:[NSURL URLWithString:photoModel.image_name]];
return cell;
}
What about reversing the order of the array:
NSArray* reversedArray = [[self.Photos reverseObjectEnumerator] allObjects];

UITableView design

I have UITableView where I want design as below.
For this I have images as below.
bottomRow.png
middleRow.png
topAndBottomRow.png
topRow.png
For this I have used below code inside -(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UIImage *selectedImage;
if (indexPath.row==0) {
selectedImage = [UIImage imageNamed:#"topRow.png"];
} else if (indexPath.row == ([products count]-1)) {
selectedImage = [UIImage imageNamed:#"bottomRow.png"];
} else {
selectedImage = [UIImage imageNamed:#"middleRow.png"];
}
if ([products count]==1) {
selectedImage = [UIImage imageNamed:#"topAndBottomRow.png"];
}
UIImageView *selectedBackgroundImageView = [[UIImageView alloc] initWithImage:selectedImage];
cell.selectedBackgroundView = selectedBackgroundImageView;
selectedBackgroundImageView = [[UIImageView alloc] initWithImage:selectedImage];
cell.backgroundView = selectedBackgroundImageView;
Now, everything works perfect.
BUT my designer is insisting on below point.
On tableview, I can have 4 cells at one time. Now let's say I have 6 rows.
Now when I have 6 rows (and tableview can show only 4), the 4th row shows bottomRow.png which is obvious. But my designer is insisting, even the tableview is scrolled, you should have same design for all 4 rows.
Edit 1
First of all, sorry for not being clear.
Well when the UITableView loads, I can only see first 4 cells even there are 6 cells because I have set the height of tableview accordingly. To see rest 2 cells, I have to scroll down. I believe this is how table view works.
Now let's say there are only 4 records. For 4 records, table view looks like image I have.
Now when I have tableview size as 6 (with id as 1-6), the fourth row gets image middleRow.png. Here what my designer wanted is to see bottomRow.png.
Now let's say I scroll down. Now I see row with cell id as 3-6. Now cell with id 3 have middleRow.png, but my designer wanted to see topRow.png.
I know this is ugly, but this is what my designer wanted to see.
Any suggestions to get this done?
One way to achieve your goal: Use numberOfRows to find out if this cell is the last cell.
In your cellForRowAtIndexPath:
if (indexPath.row==0) {
selectedImage = [UIImage imageNamed:#"topRow.png"];
.....
else if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1){
selectedImage = [UIImage imageNamed:#"bottomRow.png"];
}
EDIT:
Sorry, I misunderstood your question, I have another proposal that I think you may try...
customCell, with a custom method to set its image. For example,
[customCell setSelectedImage: [UIImage imageNamed:#"middleRow.png"];
2.
In cellForRowAtIndexPath, you can set all cells to be: middleRow.png
3.
After loading of tableView, run a checking method using [self.tableView visibleCells];
eg
- (void) setImageForTopAndBottomCells{
CustomCell *topCell = [[self.tableView visibleCells] objectAtIndex: 0];
CustomCell *bottomCell = [[self.tableView visibleCells] objectAtIndex: self.tableView.visibleCells.count-1];
[topCell setSelectedImage: [UIImage imageNamed:#"topRow.png"];
[bottomCell setSelectedImage: [UIImage imageNamed:#"bottomRow.png"];
}
If your tableView is scrollable, set your ViewController as a UIScrollView delegate, in your delegate method scrollViewDidScroll, run the setImageForTopAndBottomCells method again.
There could be better ways for achieving what you want than the one I proposed, let me know if you found one.
What about using a combination of scrollViewDidScroll:, indexPathsForVisibleRows and reloadRowsAtIndexPaths:withRowAnimation: with something like this:
Every time the table view scrolls you get the list of visible rows using the UIScrollViewDelegate method scrollViewDidScroll:
If it scrolled enough to change the background, call the UITableView's reloadRowsAtIndexPaths:withRowAnimation: passing all the index paths that needs new background
Instead of using indexPath.row == 0 to find the top you would use [indexPath isEqual:[tableView indexPathsForVisibleRows][0]] and the same thing for the other rows
Hope this helps.
You can use middlerow.png as background view of your UITableViewCell in CellForRowAtIndexPath method. Below is the code
cell.backgroundView = [[UIImageView alloc] initWithImage[[UIImageimageNamed:#"middlerow.png"]stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];
And after this you can change the Corner radius (add border color/width) of your table view. But for this first you will have to add QuartzCore framework.
self.table.layer.borderColor=[[UIColor colorWithRed:209.0/255 green:209.0/255 blue:209.0/255 alpha:1.0] CGColor];
self.table.layer.borderWidth =3.0;
self.table.layer.cornerRadius =10.0;
Hope this helps.
You can Use this:
NSArray *visible = [tableView indexPathsForVisibleRows];
NSIndexPath *indexpath = (NSIndexPath*)[visible objectAtIndex:0];
-(NSArray *)indexPathsForVisibleRows returns an array of index paths each identifying a visible row in the receiver.So once you get the visible rows, you can use the required image according to indexpath.row.

How to load more images on Lazy Loading

In mu UITable view,I am displaying images from server..For that I am using lazy loading.
I can load the images when the rows are on screen.How to increase the number of images loaded.
like- for the first time 3 table cells are visible,and the images on those cells get loaded with 2seconds delay.How can I load the images on next 3 rows at same time ?
I am using below function to load images
- (void)loadImagesForOnscreenRows
{
if ([imageArray count] > 0)
{
NSArray *visiblePaths = [tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
AppRecord *appRecord = [dataArray objectAtIndex:indexPath.row];
if (!appRecord.appIcon) // avoiding the imagen download if already has an image
{
[self startIconDownload:appRecord forIndexPath:indexPath];
}
}
}
}
Your way to do things
You can do that by downloading images on background and when they do finish, you can post a NSNotification to a method to reload tableView. But while the images are being downloaded, you have to show a loading view or something to the user to tell him that images are being downloaded.
Suggestion
I don't recommend that to you, the best way is to download each of them in background independently with SDWebImage and also make a faster response of your tableView. While the image is being downloaded you show a default image (placeholder), after the image is being downloaded this function sets it where it needs to be:
SDWebImage
You just need to #import <SDWebImage/UIImageView+WebCache.h> to your project, and you can define also the placeholder when image is being downloaded with just this code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier;
CustomCell *cell = [tableview dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
MyObject *object = (MyObject *)[self.list.array objectAtIndex:indexPath.row];
//Here is where you set your image URL and it's placeholder
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
return cell;
}
It also cache downloaded images and gives you great performance.
Why are you using this code you can just change below key value and it is just work perfectly with un limited images.
kIDStr = #"id";
kNameStr = #"im:name";
kImageStr = #"im:image";
kArtistStr = #"im:artist";
kEntryStr = #"entry";

iPhone : friend list, how did Facebook accomplished that?

I wonder if anyone can speculate or better yet provide a piece of code as for the implementation of the lengthy friends list in the Facebook iPhone app.
when you open the app and go strait to the friends list, you get the list almost in an instant, at least for me with ~500 friends.
when I try it in my own app it takes lots of precious seconds to populate the table view with the same data, so how does Facebook accomplished such a quick response time ?
upon looking at the tableview in the facebook app you notice there is no scroll bar usually found in such tableview, could that be one sign of the neat trick facebook is utilizing to achieve this rapid rows insert ? could it be they implemented some sort of a virtual tableview with only holds a few dozen rows but rotates them ?
any thoughts ?
the UITableView will let you do this. There are a number of examples on the internet with UITableView and Custom Cell's
Essentially, you load your images in the background, and you reuse the Cells that are in the tableview
EDIT Added example code to demonstrate how this is accomplished.
IMPORTANT NOTE
This code was not tested and may or may not actually function as is.
It was pasted with some editing for length. I did a lot more then this in my app, but in the interest of keeping with the example requested I omitted a lot.
On with the example:
Here is where I get the cell, load it with the items that are readily available. And send it to the background thread to load the rest.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"OfferCell";
static NSString *CellNib = #"OfferItem";
OfferCell* cell = (OfferCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (OfferCell*)[nib objectAtIndex:0];
}
NSDictionary* couponPackage = [self.jsonOfferData valueForKey:#"result"];
NSArray *couponList = [couponPackage valueForKey:#"offers"];
if ([couponList count] >= indexPath.row )
{
NSDictionary* couponData = [couponList objectAtIndex:indexPath.row];
Coupon *coupon = [[Coupon alloc] initWithDictionary:couponData];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:cell,#"cell",coupon,#"coupon", nil];
//Right here you would try to load any cached imaged from disk.
//Then send a Thread to the background to load the image.
[self performSelectorInBackground:#selector(loadTableViewCellData:) withObject:params];
//Load up the rest of the custom info into the custom cell.
[cell.captionLabel setText:coupon.name];
[cell.subTextLabel setText:coupon.subText];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
[cell setCommand:coupon.command];
[cell setParameter:coupon.commandArgs];
[cell setImageURL:coupon.imageURL];
[cell setImageAltURL:coupon.imageAltURL];
[cell setRegistrationCode:coupon.registrationCode];
[coupon release];
}
return cell;
}
as you can see, i call a background thread before i even load the custom content in the cell.
- (void) loadTableViewCellData:(NSDictionary*) objectData
{
OfferCell *cell = [objectData objectForKey:#"cell"];
Coupon *coupon = [objectData objectForKey:#"coupon"];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[coupon iconURL]]]];
[objectData setValue:image forKey:#"image"];
self performSelectorOnMainThread:#selector(setImageOnMainThread:) withObject:objectData
}
after downloading the image, i send a Main thread request to update the Image that is in the cell object.
- (void) setImageOnMainThread:(NSDictionary*) objectData
{
OfferCell *cell = [objectData objectForKey:#"cell"];
Coupon *coupon = [objectData objectForKey:#"coupon"];
UIImage *image = [objectData objectForKey:#"image"];
cell.icon.image = image;
}
##AGAIN This May not Actually Function. ##
I did not copy all of my code for this. this is a hammer out so you can get the idea.
play with the code and test it. but the fundamentals are.
Dequeue the cell that will fit your needs (Reuse Identifier)
Use the cell if it can be dequeue'd or create a new one with a reuse identifier (my example uses a xib file named OfferItem.xib)
Send a thread to the background that will load the image data from disk or url (a combination of both is recommended)
Send a thread back to the UI when you are ready to load the image into the View (Updating the UI must be done on the main thread)
if you can do that, then your friends list (or in this case offers) will be loaded up as fast as possible. and the Images will pop on the screen as soon as they download.
Also if you use a Caching technique it will be faster for subsequent loads because in the the first method {tableView:cellForRowAtIndexPath:} you would load up the cached image immediately.
Aside from that, this should load your cell's pretty fast.
They obviously load the data from a local resource (plist, ManagedObject, ...)
Have a look at some sample code to draw a TableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellIdentifier = #"MyCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellIdentifier] autorelease];
}
return cell;
}
The dequeueReusableCellWithIdentifier: thing is one reason why TableViews in iOS can draw quickly. It works somehow like this:
1)You provide an identifier for a cell you're creating.
2)Cells that are visible at first get alloced (with identifier)
3)When a Cell is moved off the screen it gets put on a pile MyCellIdentifier
4)Whenever the system needs to draw a cell of identifier:MyCellIdentifier it first looks whether there are any cells currently unused on the MyCellIdentifier pile. If that's the case it picks one off the pile and thus doesn't have to alloc a new one. That way expensive allocing can be kept at a minimum.
I hope this answers your question :)

How to improve performance while using UIWebView in cells of table view?

I am creating an application which uses a web service.And retrieves a list of users and there details like images, user id and there names.I displayed all the information related to users in table view, Thus each of the cell in the table view has an image with the for tables in it. I am using a Custom cell class to create the individual cells. selecting any row in table presents a detail view (using navigation) which show a larger image and all the details related to the particular user i selected.
in customcell and detail view class i am using web view to display image.
But when i run the app the images gets a bit of delay to display and same happens with the detail view.
Is there any alternative so that i can improve the performance of the table view so that i can have smooth scrolling of table view with out any delay in image loading and detail view??
here is the code...
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CustomCellIdentifier = #"CustomCellIdentifier ";
CustomCell *cell = (CustomCell *)[tableView
dequeueReusableCellWithIdentifier: CustomCellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil ];
//cell = [[CustomCell alloc] initwi ];
for (id oneObject in nib)
if ([oneObject isKindOfClass:[CustomCell class]])
cell = (CustomCell *)oneObject;
}
NSUInteger row = [indexPath row];
NSString *imageName = [imgArray objectAtIndex:row];
NSString *completeImageUrl = [[NSString alloc] initWithFormat:#"http://122.160.153.166:201/%#", imageName];
NSURL *url = [NSURL URLWithString:completeImageUrl];
//NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:imageData]; /// check to see if we are getting all the arrays such as image array and userId array and name array of same size..
if(image == nil)
{
}
cell.imgView.image = image; /// other wise an execption of out out array range will be shown
[image release];
[imageName release];
//[cell.webView initWithFrame:CGRectZero];
//[cell.webView loadRequest:requestObj];
//cell.webView.frame = CGRectMake(20, 0, 80.0, 64);
cell.userIdLabel.text = (NSString *)[userId objectAtIndex:row];
cell.nameLabel.text = (NSString *)[userName objectAtIndex:row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}`
i think problem can be in imgArray array as i am setting it from other class. Where i request the web service and fetched all the data about users .
Any help is greatly appreciated . Thanks in advance
I got the same problem. For that I used EGOImageCache and some thing.
Find this Url for EGOImage
Download files those names starts with "EGO", and add those to your project.
and write the following code where ever you want to put the image:
EGOImageView *imgView = [[EGOImageView alloc] initWithFrame:CGRectMake(50,50,220,360)];
NSString *imageName = [imgArray objectAtIndex:row];
NSString *completeImageUrl = [[NSString alloc] initWithFormat:#"http://122.160.153.166:201/%#", imageName];
NSURL *url = [NSURL URLWithString:completeImageUrl];
imgView.imageUrl = url;
[self.view addSubView:imgView];
Thats it. Use the similar code, where ever you want the image.
At the first time while loading it will take some time to download the image. But later it will cache the image and use it the next time.
Is there any alternative so that i can improve the performance of the table view so that i can have smooth scrolling of table view with out any delay in image loading
For this the answer is Lazy Loading of images in cells
You can implement lazy loading on webviewDidLoad which shows that webview has loaded completely
Using a UIWebView to display a single image is overkill. You should be using NSURLConnection (or one of many alternative HTTP wrappers/libraries) to load the image data and UIImageView to display it in each of your table cells. In my experience, there is no way (or at least no straightforward way) to eliminate the rendering delay when using UIWebView.
Why are you using the webview for displaying the images. Imageview should be used instead. If you are getting the images from the server then you should get those in separate thread and after you receive the images you should reload that particular row.
Some code snippet is like this:
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
...
...
UIImage *img = (UIImage *)[imagesArray objectAtIndex:indexPath.row];
if(img == nil){
[imgView setImage:temporaryImage];
[NSThread detachNewThreadSelector:#selector(getTheThumnbails:) toTarget:self withObject:indexPath];
}
else
[imgView setImage:img];
for further assistance look at this
Hope this helps.
Thanks,
Madhup
okay finally i removed the uiweb view from my app and used Imaged view and succeed.
i used the link that was given by the developer of the tweetie . here it is link text
i used the ABTableViewCell class and created the whole cell using the code.
The scrolling was very jerky when i executed the app. after applying almost 4 hours and with the help of lazy loading i was able to run my app smoothly. I stored the data which is retrieved from url into an array then applied the concept in tableView:cellForRowAtIndexPath:
method..
Thanks you guys for helping me ...
Three20 has a rich-text table view cell class (TTStyledTextTableCell I think) - should render significantly faster than an embedded UIWebView. You could also roll your own, though that would take a lot longer.