Tableview scrolling is not so smooth? - iphone

I have a table view with three different custom cells.Each will be loaded from three different cell classes.`
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"CellIdentifier";
static NSString *CellIdentifier2 = #"Cell";
static NSString *CellIdentifier3 = #"Cell";
if (indexPath.section == 0)
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil)
{
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1] autorelease];
}
cell.datelabel.text=#"dhhg";
cell.nameLabel.text=#"shdhsjdj";
cell.msg.text=#"sdhhhfhjhfj";
cell.myImageView.image=[UIImage imageNamed:#"sd.png"];
cell.likelabel.text=#"hhhf";
return cell;
}
else
{
Customcellwithimage *cell = (Customcellwithimage *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil)
{
cell = [[[Customcellwithimage alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier2] autorelease];
}
cell.datelabel1.text=#"sdhkhks";
cell.nameLabel1.text=#"sdhjkhkshd";
cell.msg1.text=#"sdsdsd";
cell.myImageView1.image=[UIImage imageNamed:#"shdjhjhs"];
cell.likelabel1.text=#"sjdh";
cell.bannerview1.image=[UIImage imageNamed:#"dshjs"];
return cell;
}
return Nil;
}
` .This is my code for the design.Can anybody help me in where i am going wrong?

Your lag is probably caused because you are loading from disc in cellForRowAtIndexpath on the main thread. Try to avoid I/o operations on the main thread. Have a look here : loading images from a background thread using blocks

Check your image size.
If image has big size, table view will not smooth

First of all cellIdentifier2 and cellIdentifier3 have the same value as #"cell".
You have only included 2 conditions, one for section zero and second for others.
You should also mention the condition for using cellIdentifier3.
You haven't mentioned what problem you are having because your code seems not to have any error.
What output do you want? Different cells for different sections??

Your Code seems perfectly fine to me. Avoid using [UIImage imageNamed:#"sd.png"] because it used to create memory issues prior to ios 3.0 however with large images it may still create problems.
You may read:
Does UIImage's imageNamed still cause memory issues on iOS4 for large images?

Related

dequeueReusableCellWithIdentifier not working with ARC and IOS 4

I can't seem to get dequeueReusableCellWithIdentifier working.
I need to build a project for IOS 4 so I can't use storyboards, but I'm using ARC.
Let's say I have 2 sections, each with 1 row.
Looking at the code below, I'm using the strong property to pass ownership, since ARC would insert the "autorelease" code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"TableCellIdentifier";
MainTableCell *cell = (MainTableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
self.retainedCell = [[MainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
However, for each row, cell is always nil (and hence a new MainTableCell is alloc'd) each time the function is called. The cell is never re-used.
This wouldn't be so much a problem except I programmatically call tableView:cellForRowAtIndexPath:, meaning I get a newly alloc'd cell each time, rather than the existing cell.
The only method I can see is to add the cells to an NSMutableArray.
Is there something I'm missing with dequeueReusableCellWithIdentifier now?
Thanks!
EDIT
I'm using the code below to get the cell. As mentioned it's creating a new cell not re-using the one that should have been already made + retained.
I don't need to invoke reloadData for all the rows, just change a specific one.
MainTableCell *cell = (MainTableCell *)[self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
[self configureCell:cell atIndexPath:indexPath];
You happen to be de-queuing MainTableCell, and then you proceed to check if it is nil, at which point you use a completely different var to alloc a table cell. What the heck? Try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"TableCellIdentifier";
MainTableCell *cell = (MainTableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[MainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}

update uitableview cell object

i have a tableview that contains a uiwebview in its first row. i would like to change this tables' webview object with new one when user clicks a button. i am using the code given below but it does not work fine. older object is there and the newer one is over it although i recreate the webview. how can i remove the older one from cell?
thanks...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"NİL.......");
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
} else {
NSLog(#"NOT NİL.......");
}
[cell addSubview:webView];
return cell;
}
Since you are using "dequeueReusableCellWithIdentifier", your should reconfigure the cell each time when the cell is displayed.
Please remember that the cells with same identity will be reused. It's better to set the same identity to one particular type of cells, typically cells with same subviews and layout.
This is sample for how to load data and reconfigure a cell: http://code.google.com/p/tweetero/source/browse/trunk/Classes/MessageListController.m
Here is a tutorial to get familiar with UITableView:
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/TableView_iPhone/CreateConfigureTableView/CreateConfigureTableView.html

UITableView not scrolling smoothly...(iPhone SDK) ..!

UITableView not scrolling smoothly...(iPhone SDK) ..!!
I have implemented UITableView DataSource and Delegate methods in an individual separate classes.(one for delegate and one for datasource) in main program i write only:
//assume that all objects are allocated
ObjTableView.dataSource=ObjDataSource;
ObjTableView.delegate = ObjDelegate;
[self.view addSubView: ObjTableView];
when i run this code , UITable view appears but when i try to scroll it, it doesn't scroll smoothly.
I have also checked that UITableViewCell doesn't redraw once the cell is initialized.
can any one tell me why this happens ? How can i solve this problem ??
From comments:
ListDataSource *ObjListDataSource = [[ListDataSource alloc]initWithArray:[[sender object] valueForKey:#"List"]];
ListDelegate *ObjListDelegate = [[ListDelegate alloc]initWithArray:[[sender object] valueForKey:#"List"]];
tblList = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
tblList.dataSource = ObjListDataSource; tblList.delegate = ObjListDelegate;
[self.view addSubview:tblList]; [tblShopList release];
More from comments:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:#"%i",indexPath.row];
UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0,0,320,100) reuseIdentifier:CellIdentifier] autorelease];
//custom cell code
}
return cell;
}
More Information:
I have used NSNotification which notifies to current class when parsing is complete, after receiving notification , current class method calls DataSource, Delegate methods (which is defined in a separate class file).
So UItableViewCell customization (which is in ListDataSource) and table view(in current class) both are in different classes.
A problem is
NSString *CellIdentifier = [NSString stringWithFormat:#"%i",indexPath.row];
The id needs to be the same for all cells of the same class, otherwise you never reuse them. As you can see in most examples, it is indeed a constant in most (all?) cases.
Little explaination on the reuseIdentifier: every time a cell gets out of screen, you can reuse it instead of creating a new one. To reuse it, you need a cell in queue with the same identifier as the one you pass to dequeueReusableCellWithIdentifier. The way you did, the cells are never reused, because each id is unique (they may or may not be reused in case a row reappears on screen, depending on queue size, which is not configurable AFAIK). This is why personalization of the cell should happen OUTSIDE the "cell == nil" block. Long story short, you are using the reuseIdentifier not as intendend.
I think Michele is correct, but I would also add that it looks like you are doing your cell customization where the cell gets created. What you should be doing is something more like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = (UITableViewCell)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0,0,320,100) reuseIdentifier:CellIdentifier] autorelease];
//custom REUSABLE cell code here, e.g. text color, etc.
}
NSString *cellText = [dataArray objectAtIndex:indexPath.row]; //assuming you have a simple array for your data
cell.textLabel.text = cellText;
return cell;
}
I would also add that I'm not sure why you are able to run the app with the code you have here, since UITableViewCell cell = ... is an invalid initializer. It should be UITableViewCell *cell = ....
It would be helpful to see how you are customizing your cell, since without that it's hard to see what's happening.

UIWebView as part of a UITableViewCell: leading to crash because of a thread lock

I'm trying to add a UIWebView as a subview of a UITableViewCell in order to display some data formatted with MIMEType 'application/xhtml+xml'.
Even just initializing the UIWebView as described in the following code leads the application to crash!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cellForRowAtIndexPath: '%d' in section '%d'", indexPath.section, indexPath.row);
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
UIWebView * webView = [[UIWebView alloc]initWithFrame:cell.frame];
return cell;
}
I'm getting this message:
bool _WebTryThreadLock(bool), 0x10a7f50: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...<
I can not figure out where I'm doing wrong!
Thanks for help
Gerald
The error message tells you what's going on: You are probably not on the main thread? You should only access UIKit from the main thread.
Additionally, cell.frame is most likely not what you want here. Try to set a fixed size with CGRectMake(...). And don't forget to add it. :-)

UITableView doesn't reuse cells?

Good morning all.
I'm having a small crisis with table views in a 3.1 app. I have a table view with some complex tableViewCells being loaded from a nib, and they're not being reused. Feeling it might have something to do with loading them from a nib, I decided to try a simple test project to see if cells are being reused using nothing but the basic apple template code. I started with the Navigation Based Template and here's the code for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = [NSString stringWithFormat:#"%d", indexPath.row];
return cell;
}
I have a breakpoint set at the following line, and it's getting called on every pass.
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]
Setting the reuseIdentifier in the constructor as such:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"] autorelease];
}
Yields the same result, no cell reuse.
Thanks in advance for any help you can offer!
The table will usually create and use a few cells (5 or so usually) before it needs to start reusing them. This of course depends on how big they are and how many appear on screen at any given time. Nothing to fret about.
I am not sure what you mean by everytime, everytime the app opens ?
Run the code with object allocation tool and look at the graph for object allocations as you scroll through the tableview . If object allocations are increasing linearly even after few scrolls . Then you have a problem.
Try to make the CellIdentifier static, e.g.
static NSString *CellIdentifier = #"Cell";