UITableViewCell not showing until scrolling - iphone

I'm having an issue where my UITableViewCell's image (I customized it into a cell with just the image) is not showing up after being downloaded unless you have scrolled down to make it invisible and scroll up to see again.
I am using HJCache for asynchronous image downloading as well as caching. What I am not sure is if this was the issue with HJCache or my UITableViewCell and how to fix it.

When the image has finished downloading (assuming the cell itself is the delegate for the asynchronous call), call [self setNeedsDisplay] which will redraw the cell. This is what happens when the cell is reloaded because of scrolling.

Well, I'm just going to answer my own question since I had found the most ridiculous solution.
After trying out various methods and headaches, I deleted the app ( + cache) from the simulator and everything seems to be working properly again.
My best guess is that the locally stored unfinished images by HJCache were messing up.

As soon as your data is finished loading, call [tableView reloadData]; This will make the tableView reload all of it's cells that are currently visible.

When you set up the cell set the image to nil. If that doesn't work set the image to a default locally stored image of the same size web if it's just completely white.

Related

Strange UITableViewCellStyleSubtitle + [cell imageView] behaviors

This question's been bugging me for a month and i've been resisting posting about it, but I can hold out no longer. Here's what's going on:
I have an app with UITableViewCells, all initialized as UITableViewCellStyleDefault. For each one, I am setting the image view's image using the excellent SDWebImage package, which extends UIImageView to have a method for [UIImageView setImageWithURL:(NSURL*)url placeholderImage:(UIImage*)image].
The problem is that the images are showing up more narrow than they should be, on the tableView, but for some reason selecting a row makes it the correct size. So does scrolling the row off screen, then onscreen, then offscreen.
What method should I be using to force cells to redraw? I have found a few conflicting ideas and none of them have worked so far. I feel like there's a simple call to UITableView to UITableViewCell I'm missing out on. Also, where do I put this call? I have tried calls in cellForRowAtIndexPath and willDisplayCell .
Thanks for your help!
SDWebImage: https://github.com/rs/SDWebImage
I solved the issue - I had to just make my SDWebImage placeholder images the same aspect ratio as the images I'm trying to load. As my server forces all my images to be 95x95, this was a relatively easy fix; I simply updated my placeholder.png to also be 95x95 (instead of some odd dimension it was, like 92x132)
[[cell imageView] setContentMode:UIViewContentModeScaleAspectFit];
this line makes the imageview show the image in its original resolution but fit to the image view size.
the main drawback is if u have the images in different sizes then each image will show i different sizes.... it should not looks good...

UIImage not load in UITableView with lazy image loading

When I scroll to new area of the UITableView with lazy image loading, then
immdietly scroll back to the old area, no matter what I do now, the new area will not show new images.
My code is based on apple lazy table view.
Till now I thought it was something with the web server, but I had cache functionality now, and all images are loaded from iphone files, so for sure there is somthing wrong in my code.
Again, the images are not shown ONLY in that case :
UITableView is loading the data
All visible cell are showing the images correctly.
If I scroll to new area, move to old area *quickly* and move back to new area the image will not load, no matter where I scroller now(only the images in the new area that I quickly scorll back from will not load)
all on other cases, the images are shown correctly.
Without seeing the some code its hard to say. If your display is tied to a callback from the NSURLConnection you might be losing your reference to the delegate.
When you scroll the cell view get repopulated with the data in the new cell. If the NSURLConnection is running outside of the cell view you might be losing the reference to it's delegate. When the NSURLConnection is completed if it doesn't have a delegate to fire the complete method then it won't get called. When you scroll to the new cell the NSURLConnection is already complete so it doesn't call the completed again and the spinner just keeps going.
I fix it. the bug was nothing to do with all above. so nothing to share and learn from.
I thought it is important for other I'll be clear about that, so no one will be confused about what I wrote earlier.
The process of checking if image already download was wrong.

iPhone - UITableView reload on scrolling

I've a UITableView and each UITableViewCell displays a unique UIImage which is fetched from internet. As we scroll the UITableView, cells are recreated and tableView: cellForRowAtIndexPath: gets called every time to configure cells. So it loads UIImages again and again from internet and scrolling is not smooth.
The solution I found for myself right now is to create NSMutableArray of all those UIImages on ViewDidLoad then load images into UITableViewCells from that NSMutableArray which is for sure giving me smooth scrolling.
My concern with my own solution is that when I keep all UIImages in NSMutableArray and those all objects are kept in memory for as long as application runs, I am most probably making inefficient use of memory.
Is there a better, more efficient way to do this which gives me smooth scrolling as well as best memory usage?
I think this example will help you..
http://kosmaczewski.net/2009/03/08/asynchronous-loading-of-images-in-a-uitableview/
Cache the downloaded images on the filesystem. When loading a cell, first ensure that a cached copy of the associated image is available, then load it using [UIImage imageWithContentsOfFile:].
You should go with array of image link instead of the image.
You should load image asynchronously so that it will improve performance of creation of the UITableviewCell.
Verify that you are using dequeueReusableCellWithIdentifier, it will give you the smoother scrolling.

UITableView cells with both UIActivityIndicator & UIProgressView

I have a UITableView that contains several cells and some of them (the ones for files that are still uploading) have both an UIActivityIndicator and an UIProgressView. The ones for files that are finished use a different icon (instead of the activity indicator) and hide the progressview.
This table is using a NSFetchedResultsController as data source, so I get the updates on the data model and update the content.
Everything works just fine. The problem, however, is performance. Every time I call reloadData my UIActivityIndicators flicker, and it's not very smooth. Although I'm caching from the nib file, reloadData will have to calculate the new progress % for the ProgressView and I don't do anything with the ActivityIndicator other than hiding it if upload is complete.
Anybody ever tried something similar? Is there a workaround?
I was thinking about having an array of my progressview references and use that instead of calling reloadData.. not sure if this is the correct approach.
Thanks,
Fernando
When you call reloadData on the UITableView, all the cells of the table view are completely refreshed, re-assembled and redrawn. All the old ones are thrown away. This means that all the subviews of the UITableViewCells are removed and re-created too (including your UIActivityIndicator and UIProgressView). The refresh causes these views to flicker, or perhaps jump back to their start state. As there is no way of setting the frame of a UIActivityIndicator, your suggestion of restoring some progress value simply isn't possible.
Instead, perhaps you should try and engineer your "refresh" to not require a complete refresh of the table? For example, if you want to change the text of a UITextField within the view, you could simply access this text field and set the text property (no refresh is required). Or, if you want to hide your progress indicators, you could go into the appropriate object instances and set their property. You should design your app so that this is possible. Making changes this way avoids having to reload cells from scratch.
Besides the benefit of fixing your problem, using this method of updating, you should also see a large performance increase. reloadData is a very costly method to use and should be only used if it is absolutely necessary to really re-create the entire UITableView from scratch.
Hope this helps. :)

Progressive download of images in a UITableView

I'm developing on the iPhone and I have seen in the AppStore that the images are progressively downloaded in the UITableView... How can I implement that?
My idea was to detect the showed content (which cells are shown) and download these images. My problem is that I don't know how to detect the showed cells!
Is it the good way to do it?
Best
The way this was demonstrated at the iPhone Developer Tech Talk was to use NSOperation and NSOperationQueue.
The idea is to wrap up your image download request (using NSURLRequest) into an NSOperation.
You can set your cell as the receiver of a call back sent by your operation when it's complete so that you can attach the image to the cell (draw it manually, or add it to an image view).
Then basically, in your cellForRowAtIndexPath method, tell the cell to start the image download, and have the cell create an NSOperation and add it to the operation queue managed by your table view controller or something.
The queue will start executing the operations and call back to each cell when they're done.
If you want to, you can cancel the operation if the cell moves offscreen, so you don't waste resources downloading an image that will be thrown away because the cell won't be visible to display the image.
Here's an example of how to do this that implements the basic idea that Jasarien talks about. It may be sufficient depending on your application's needs and is generally good example of how to do it if it isn't.
I would implement each cell as a subclass of UITableViewCell and then override willMoveToWindow: method in the subclass. willMoveToWindow: is called when the cell view becomes visible on the screen or when it goes off screen (newWindow gets nil). Then each cell can queue a request to load its image as it becomes visible (and maybe even cancel its queued request if it goes off screen).
BTW, You can use the visibleCells property of UITableView to get the list of cells that are visible.
#Jasarien: nice answer
Or you can use the three20 project if you want. there is a TTTableViewController that already handles all the stuff you want. you only have to input the URL to the imageview and viola.
TT also caches your images in memory or also on disk.
check out the sample project bundled in three20 gitbub ressource. there an example.
That is calles LazyTableView...You can gt tutorial from here
http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html
Please go through this link , and try to integrate Lazy table view load , you can achieve you output , http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/ change the url in ProgressiveImageDownloadViewController in Download button click method.