iPhone - Slow scroll on TableView - iphone

i've problems with the scroll of my Table View. I have a custom cell that i load with this code :
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CustomCellQuartieri" owner:self options:NULL];
cell=customCell;
}
This is the code. customCell is an UITableViewCell object with a own xib. The controller of the xib is my view controller where the table is placed in. I load 2 label and one imageView from the internet. What is the problem? And how can i make my custom cell reusable?
Thanks

To make your custom cell reusable, set the identifier propertie in Interface Builder.
Who do you load the data from the internet (Async)?

Since you are using a custom UITableViewCell you have to set the identifier string property through Interface Builder, and then dequeue the cell in the usual way, using that same string as the key. This way your app will not create a new cell for each row of the table, but will reuse the already present cells, reducing build and presentation times.
If this won't fix the issue, you should look at the internet connection, to understand why data loading is so slow. If you own the server that serves the data, you would try to speed it up, otherwise you should look for a different or more efficient way for loading data remotely. Some code example would be great.
Edit
As stated in the comments, the slowness could be related to the loading time of remote images. You could try to build a local dictionary, of something similar, in which you'll save the images you already loaded associating them to their URL as the key, while you'll read remotely those you still don't own. This will work like a local cache to improve loading time for remote data.

The problem was that images have to be loaded asynchronously. Search SDWebImages on Google.

Related

Lazy Loading for multiple UITableView in one view

I am working on iPad app. And I am using 2 tables in one view and images urls are coming from
web services. I am using Apple provided lazy loading for both tables, and there are 2 web-service called for showing the two tables data, one is calling in ViewDidLoad() and second is calling in callback method of first web service. And I am facing problem in this method.
- (void)appImageDidLoad:(NSIndexPath *)indexPath withDataReceived:(NSData*)receivedData
The values for indexpath.row values are changing every time , some time it gives correct value and some time not.
Can anybody please help me for that.
Thanks in advance.
you might have to pass in which tableview also.. you kno how it is passing indexPath to that method.. modify it to pass tableview.. and inside the method.. check which tableView and then get the right data source array for appropriate tableview..

Designing a view controller with multiple xibs

Is it a best practice to use more than one xib in a view controller for a responsive design?
I'm currently implementing an app that relies heavily on a remote API for its data. One particular view is troubling since the layout depends on the data returned from that API. It is either a product that has a full review and pricing, or a product that we only have limited information on.
The design is responsive to the data. Depending on how much information that is returned, the view has a layout that is much different from the other. Also, there's a quite a few elements that need to be repositioned depending on text length, etc. I had originally implemented the design nearly all in code, but that became quickly unmaintainable so I offloaded almost all of it to the xib and only use code to reposition elements.
Using more than one xib might be a good solution. When the view loads, the controller performs the API request, then loads the new xib if need be. I'm not sure of what downsides there may be to this approach.
I'm implementing now the client-server app. Layout of the most of views is also depending on data from API. In situation like yours I've created several xib files (one for detailed product, one for limited etc.) and depending on server response I'm choosing xib to load. Code sample:
// load proper view from nib
NSArray *nibViews;
if(product.details) {
nibViews = [[NSBundle mainBundle] loadNibNamed:#"DetailedView" owner:self options:nil];
}
else {
nibViews = [[NSBundle mainBundle] loadNibNamed:#"NormalView" owner:self options:nil];
}
// create and initialize product view object
ProductView *productView = [nibViews objectAtIndex:0];
// configure a view here..
Yo could put all versions of view into one xib. In that case you only change index in nibViews objectAtIndex:

How can I create a UITableView with selectable options?

I'm looking to create a grouped style UITableView that allows a user to select different options (like shown below). I'm already able to setup the UITableView in a grouped style; my question is based on how I can add buttons, toggles and list options like shown below? Is it possible to make use of plist's to simplify the process somewhat?
Note: I'm not trying to create a 'settings' view, I want to allow users to create lots of different NSDictionaries and set values on each of them using the table setup described.
You should create your own UITableViewCell. This way you could add the desired UI items of your choice. You could use the Interface builder to create your custom cell. There are many good tutorials on the subject.
I do not see the need to use a property list for this, since it is rather simple to implement this.
This is a good example:
http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html
You should look a this library : http://www.inappsettingskit.com/
Other exist but I don't remember the name. Or you can define your own data structure in plist, and associate with UITableViewCell type. But this will require a lot more coding.
For adding a UISwitch to a UITableViewCell, you may want to have a look at the answer to this question on SO.
your answere lies in the delegate method didselectrowatindexpath. if you want to add options to the individual cells, you'll need either a custom uitableviewcell or set things in generic uitableviewcell accordingly. also, a notable mention would be to look into tableView:accessoryButtonTappedForRowWithIndexPath:
next you should use the plist as follows to read it:
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"league" ofType:#"plist"];
contentArray = [NSArray arrayWithContentsOfFile:plistPath];
This could be called in your [uitableview cellForRowAtIndexpath:] delegate method and parse it accordingly
cheers~
fy

in iphone uitable view data desplay problem

i have a uitableview in that i display data with the help of network queue . I use CellIdentifier like this,
NSString *CellIdentifier = [NSString stringWithFormat:#"%i_%i" , indexPath.section , indexPath.row];
and check condition
if(cell ==nil)
{
}
so data is loaded only one time .
by doing this, it loads data but the problem is in imageview. the image size is big so it takes some time. if image is not loaded and user scrolls the table then that image is never seen. To see the image we have to wait till it is loaded and then we scroll the table.
Is there any way to load the image again which are not loaded.
I dont want to load all data again .
You understood if(cell == nil) {} wrong.
This condition should not be used so your data is only loaded one time, this should be used to construct a new cell only when necessary.
You have to setup each cell outside of this condition.
And you should definitely not use a different CellIdentifier for each cell. This is a bad hack introduced by people who are to "lazy" to implement lazy loading of cell images correctly.
You should see the LazyTableImages example from apple to see how it should be done.
For loading images in table view, you can use good LazyTableImages Example by Apple. You don't have to write this type of code (different cell identifier for each). You have to reuse table view cell as per apple document otherwise it will take too much memory while scrolling.

TTTableImageItem doesn't load the image until scroll

I'm using the three20 project for my iPhone app. I've narrowed my problem down and I'm now just trying to re-create the 'Web Images in Table' example that comes with the project. I've copied the code exactly as in the project, with the exception that I do not use the TTNavigator (which the example does) but I am adding my TTTableViewController manually to a tabBar.
The problem is as follows; the images in the table should load automatically from the web, like in the example. But they only load after I scroll the table up and down.
In the console it clearly says it is downloading the images, and you see the activity indicator spinning like forever.. And unless I scroll up and down once, the images will never appear.
Anyone? Thanks in advance.
P.S:
If I'm using this code in any random UIView, It also doesn't work (only shows a black square):
TTImageView* imageView = [[[TTImageView alloc] initWithFrame:CGRectMake(30, 30, 100, 100)] autorelease];
imageView.autoresizesToImage = YES;
imageView.URL = #"http://webpimp.nl/logo.png";
[self.view addSubview:imageView];
If I put this code in my AppDelegate (right onto the window), it does work .. strange?
POSSIBLE SOLUTION:
Although I stopped using TTImageView for this purpose, I do think I found out what the problem was; threading (hence accepting the answer of Deniz Mert Edincik). If I started the asynchronous download (because basically that is all the TTImageView is, an asynchronous download) from anywhere BUT the main thread, it would not start. If I started the download on the main thread, it would start immediately..
Sounds like a threading problem to me, are you creating TTImageView in the main runloop?
I find one interesting thing. When I use combination TTTableViewController, TTTableViewDataSource and TTModel I have same problem with loading TTImageView. My problem was, that my implementation of Model methods 'isLoading' and 'isLoaded' don't return proper values after initialization of model. That forces me to call reload on model manualy in 'viewDidAppear' method and that causes image loading problem. So I repair my 'isLoading' and 'isLoaded' methods to both return 'NO' after Model init, and everything is fine.
When an image finishes loading try sending a reloadData message to the table view. This forces the table to recalculate the size of the rows and redraw the table. Just be careful that you don't start downloading the image again in response to this message.
I've written something similar to this where an image view will load its own image from the web.
Im my experience, when the image had loaded successfully but was not shown in its view, it was a case that the cell needed to be told to redraw.
When you scroll the table view, the cells are set to redraw when the come onscreen, which is why they appear when you scroll.
When the image loads, tell the cell that it is sitting in to redraw by sending it the message setNeedsDisplay.
That way, when the image finishes downloading, the cell its sitting in (and only that cell) will redraw itself to show the new image.
It's possible that you might not need to redraw the entire cell and might be able to get away with simply redrawing the image view using the same method call. In my experience, my table cells view hierarchy was flattened, so I had to redraw the whole cell.
I don't have an answer for what you want to do, but I will say that this is considered a feature, and the expected behavior. You use TTImageView in UITableView when you want to do lazy loading of images. TTImageView will only load the images whose frames are visible on the screen. That way, the device uses its network resources to download images that the user has in front of them, rather than a bunch of images that the user isn't even trying to look at.
Consider having a long list that may contain a couple hundred thumbnail images (like a list of friends). I know from experience that if you kick off 100+ image requests on older devices, the memory usage will go through the roof, and your app will likely crash. TTImageView solves this problem.
This is a thread problem. You can load the images by including the line:
[TTURLRequestQueue mainQueue].suspended = NO;
in - (void)didLoadModel:(BOOL)firstTime.