I have a UITableView showing over 50 custom-designed cells. The table shows ok, but if I scroll the table, no cells ever get reused. Instead my app just keeps loading new cells all the time, which is very slow on my iPhone 3.
What could be causing this problem? Here's a code snipped from my UITableViewSource.GetCell() method
var dequeuedCell=tableView.DequeueReusableCell (identifier);
//try to reuse a previously recycled cell, create a new one if none exists
var cell = (ITimeEntryTableCell)dequeuedCell;
if (cell == null)
{
//load a new cell using the XIB file definition
NSBundle.MainBundle.LoadNib (identifier, tableViewController, null);
cell = tableViewController.DurationCell;
tableViewController.DurationCell = null;
}
Thanks,
Adrian
Edit: Please note that I am using Monotouch, not objective C...
Have you set the cell identifier in your xib file? If this is not set, your cells won't be dequeued.
In the interface, declare: TableViewCell * aCell, and try using this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
static NSString * CellIdentifier = #"TableViewCell";
TableViewCell * cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; // hooks up cell for us.
cell = aCell;
}
return cell;
}
Hope that Helps!
This is the code that works perfectly -
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"cell1" owner:self options:nil];
cell = self.oneMessage;
self.oneMessage = nil;
}
return cell;
}
UPDATE: for monotouch, try this -
public override UITableViewCell GetCell(UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(this._cellIdentifier);
myTableViewCell mycell = null;
if (cell == null)
{
mycell = new myTableViewCell();
NSBundle.MainBundle.LoadNib("RootViewController", _controller, null);
_controller.myTableCell = new myTableViewCell();
mycell = _controller.myTableCell;
cell = new UITableViewCell(UITableViewCellStyle.Subtitle, this._cellIdentifier);
}
else
{
mycell = (myTableViewCell)cell;
}
Make sure that the "identifier" is an NSString, as this could be used as a token internally, instead of a a string-content comparison.
So:
NSString identifier = new NSString ("myID");
Related
Create a Table View.
then create a customize table View cell and place a button on cell and Now I try to get Table View index when click on index.
But when I click on button that place on cell It's not giving me the Index of list.
My Table View class name is SubMenuViewController and cell class name is SubMenuCell
and my code of SubMenuViewController is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ModelLocator *model = [ModelLocator getInstance];
static NSString *simpleTableIdentifier = #"SubMenuCell";
SubMenuCell *cell = (SubMenuCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SubMenuCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (model.foodSubItemList) {
FoodSubItemVO* foodSubItemTemp = [model.foodSubItemList objectAtIndex:indexPath.row];
[cell.lbSubFoodItem setText: foodSubItemTemp.foodSubItemName];
[cell.lbPrice setText: foodSubItemTemp.price];
[cell setIndexPath:indexPath];
}
return cell;
}
and My SubMenuCell code here
- (IBAction)addItemIntoOrder:(id)sender {
NSLog(#"#%",indexPath);
NSLog(#"#%",indexPath.row);
}
indexPath declare in SubMenuCell.h
Your NSLog's are faulty; try this instead (mind that changed % and # order).
- (IBAction)addItemIntoOrder:(id)sender
{
NSLog(#"%#",indexPath);
NSLog(#"%#",indexPath.row);
}
Make sure that the addItemIntoOrder: action is hooked up to your delegate correctly in IB.
I'm trying to implement "Load more..." on a tableView. I've done it, but I don't know if it's efficient.
The thing is that I have custom cells, and if I do like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
ArticlesCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ArticlesCell" owner:self options:NULL];
cell = (ArticlesCell *) [nib objectAtIndex:0];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
tableView.backgroundColor = cell.backgroundColor;
if (indexPath.row <= (self.bookmarks.count - 1)) {
[self configureCell:cell atIndexPath:indexPath];
}else{
cell.textLabel.text = #"Load more...";
}
return cell;
}
It works great but what happens is it's reusing the cells, and if I scroll, every fifth cell (this is height 77.0) will have the label "Load more...", but actually do it's job as normal.
I found this workaround, but I don't know is it good and efficient.
Here it is:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
if (indexPath.row <= (self.bookmarks.count - 1)) {
ArticlesCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ArticlesCell" owner:self options:NULL];
cell = (ArticlesCell *) [nib objectAtIndex:0];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
tableView.backgroundColor = cell.backgroundColor;
[self configureCell:cell atIndexPath:indexPath];
return cell;
}else{
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = #"Load more...";
return cell;
}
}
As you can see I'm making the "Load more..." cell a simple UITableViewCell, and not reusing it, since it's only one. Is this good approach? Can you advice me in something better?
Thank you!
Another approach would be to use 2 different cell identifiers, one to identify and reuse (once initially created) an ArticlesCell and another to identify and reuse (once initially created) a "Load more..." UITableViewCell. At least then you will only create the "Load more..." UITableViewCell once rather than every time it scrolls into view.
static NSString *ArticleCellIdentifier = #"ArticleCell";
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
The LazyTableImages Apple iOS sample project uses a similar approach (see the Classes/ RootViewController.m).
When you are click on loadmore button then increase the number of rows and reload the tableview . i.e in the method numberofrowsinsection.Let me know if you need any more
I have a UITableView that I am populating with custom UITableViewCell in interface builder. I am having some issues accessing these custom tableviewcells properties and am hoping for some help.
In Interface Builder I am setting the custom tableviewcell's class to the current View controller (so I can assign all of the label objects to the correct labels in Interface Builder), So I have also set up the IBOutlet labels to the correct labels in Interface Builder However this error occurs when I try to pass the NSString from the array object variable (which is of type NSString) to the UIlabel's text.
Property 'cellDescription' not found on object of type 'UITableViewCell *'
Below is the code I have used to set up my tableview with the custom tableviewcell and then try to populate the cells UILabels with the correct text..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (indexPath.section == 0) {
// Set cell height
[self tableView:tableView heightForRowAtIndexPath:indexPath];
// Configure the cell using custom cell
[[NSBundle mainBundle] loadNibNamed:#"AutomotiveSearchCell" owner:self options:nil];
cell = autoSearchCell;
//call dataArrayOfObject that has all of the values you have to apply to the custom tableviewcell
SearchResultItem* myObj = (SearchResultItem*)[dataArrayOfObjects objectAtIndex:indexPath.row];
cell.cellDescription.text = myObj.seriesDescription; // This is where I am receiving the error
NSLog(#"%#", myObj.seriesDescription); // This logs the correct value
//Disclosure Indicator
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
you must typeCasting UITableViewCell To AutomotiveSearchCell
I think you code somewhere is strange(There is no declaration for autoSearchCell), but you must do the following.
cell = (AutomotiveSerachCell* )autoSearchCell;
The above code does not work, should following code.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
convert to
AutomotiveSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
If that does not work above, refer a following process.
make a CustomCell Class.
make a CustomCell xib.
linked label to CustomCell Class.
import header #import "AutomotiveSearchCell.h" and following code copy and paste.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AutomotiveSearchCell *cell = nil;
if(!cell)
{
UINib *nib = [UINib nibWithNibName:#"AutomotiveSearchCell" bundle:nil];
NSArray *arr = [nib instantiateWithOwner:nil options:nil];
cell = [arr objectAtIndex:0];
cell.cellDescription.text = #"Test~!~!~!";
}
// Configure the cell...
return cell;
}
I am having trouble getting my CustomTableViewCell, a subclass of UITableViewCell to appear in my table view.
I am using a xib to represent that cell, but I am assuming that the code for the data source delegate doesn't change. I made sure to set an identical reuse identifier inside the table view cell XIB.
I isolated the problem to the fact that the datasource method that returns the table cell isn't working correctly, here it is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
DataObject *foo = [self.dataArray objectAtIndex:indexPath.row];
if (cell == nil)
{
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[[cell overview] setText:foo.overview];
[[cell price] setText:foo.price];
NSLog(#"cell initialized, description text is %#",cell.overview.text);
return cell;
}
Not sure why this isn't working, but that last log statement always prints a (null) at the end, and yes I did verify that the overview property of the data object has a valid string in it. Same thing for price.
1) Make your Custom cell class separate
2) XIB : File Owner class change to NSObject
3) XIB : UITableViewCell change to MyTableViewCell
4) Where you want to add inside table view code as
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MyCell";
MyTableViewCell *cell = (MyTableViewCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *arrayCellXib = [[NSBundle mainBundle] loadNibNamed:#"MyTableViewCell"
owner:self
options:nil];
if (indexPath.row == 0) {
// first table cell
cell = [arrayCellXib objectAtIndex:0]; // *
......
}else {
cell = [arrayCellXib objectAtIndex:1]; // *
}
...
}
return cell;
}
Object at index 0,1 ... are index for which order you make MyTableViewCell in xib, if you want to have more than one custom cell. means in a MyTableViewCell class u make unlimited custom cell and use according to requirement.
Normally, just make ONE custom cell in the XIB and do exactly this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int thisRow = indexPath.row;
NSString *exampleText = [yourData objectAtIndex:thisRow];
static NSString *CellID = #"cu5";
FancyCell *cell =
(FancyCell *)[tableView dequeueReusableCellWithIdentifier:CellID];
if (cell == nil)
{
NSArray *cellTeam =
[[NSBundle mainBundle] loadNibNamed:#"FancyCell"
owner:self options:nil];
cell = [cellTeam objectAtIndex:0];
}
[cell someFunction:exampleText];
[cell.someLabel setText:exampleText];
return cell;
}
Hoping may help u :)
In .h file, you write it.
IBOulet CustomTableViewCell *tableCell;
and connect to File's Owner in CustomTableViewCell's .xib file.
You modify this in (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"CustomTableViewCell" owner:self options:nil];
cell = tableCell;
}
I think it will be helpful to you.
I have a tableview displaying data using a custom UITableViewCell(say cell1). On touch of a row, I change the custom cell to another custom UITableViewCell(say cell2). Also I increase the size of row of the selected cell to accomodate, more items of cell2.
My problem is that the approach works fine when the number of rows in table view is less. When the number of rows increses, the rows expand on touching, but the data displayed is same as that of cell1. Cell2 doesn't seem to be loaded at all.
Looking forward for a reply soon....Thanks in advance.
I am posting my code....please let me know if there is a problem in that.
My cellForRowAtIndexPath looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath == selectedCellIndexPath)
{
static NSString *Identifier1 = #"Identifier1";
Identifier1 = #"cell2";
CustomCellController1 *cell = (CustomCellController1 *)[tableView dequeueReusableCellWithIdentifier:Identifier1];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CustomCellController1View" owner:self options:nil];
cell = rowTwoObject;
}
[cell setText:[test1Array objectAtIndex:indexPath.row]];
return cell;
}
else {
static NSString *Identifier2 = #"Identifier2";
Identifier2 = #"cell1";
CustomCellController1 *cell = (CustomCellController1 *)[tableView dequeueReusableCellWithIdentifier:Identifier2];
if(cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CustomCellController1View" owner:self options:nil];
cell = rowOneObject;
}
[cell setText1:[temp1Array objectAtIndex:indexPath.row]];
[cell setText2:[temp2Array objectAtIndex:indexPath.row]];
return cell;
}
}
didSelectRowAtIndexPath looks like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedCellIndexPath = indexPath;
[tableView reloadData];
}
heightForRowAtIndexPath looks like this:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if(selectedCellIndexPath != nil
&& [selectedCellIndexPath compare:indexPath] == NSOrderedSame)
return 110;
return 60;