I do not understand why my cell.detailTextLabel.text is null.
static NSString *CellIdentifier = #"Cell";
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyId];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
/*[[NSBundle mainBundle] loadNibNamed:#"CellTest2" owner:self options:nil];
cell = mealPlanCell;*/
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
//self.mealPlanCell = nil;
}
cell.detailTextLabel.text = #"Test";
It will let me set the cell.textLabel.text to a value but not the detail one.
I figured out the reason if you leave
if(cell == nil){...}
around the cell = [[[UITableViewCell alloc]...
then the cells will not re render and thus will not update the style and or details so if you remove the if() then this will allow you to re render each cell in the table view if you are changing style back and forth. This is not a good thing to remove though if you think about it cause then it is going to low the tables "speed" which probably wont be noticeable but it is something to consider looking into as a possible issue. This is not what I did to solve the problem personally cause I choose to take a different approach but it is something that worked when I tried.
I had same problem: UITableViewCell initWithStyle:UITableViewCellStyleSubtitle is not working
For those that search and find this question... and have same problem as me, where you are using a prototype cell and the style is not defined correctly in the storyboard.
If your rowHeight is not tall enough, the cell.detailTextLabel.text won't be visible even if the cell.textLabel.text is visible. A rowHeight of 22 seems to be the minimum with the default font.
Related
You can assume my cell is complicated enough, In order to reduce the coupling, I want implement the cell by child MVC, my sample code like this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
CellViewController *cellVC = [[NSBundle mainBundle] loadNibNamed:#"CellViewController" owner:self options:nil].lastObject;
[self addChildViewController:cellVC];
[cell.contentView addSubview:cellVC.view];
cellVC.view.frame = cell.bounds;
}
return cell;
my cellViewController has a function - updateUIWithModel:
now, my question is:
1) using MVC like this is right?
2) if right, how can i set the data to cellVC?
You need to add UITableViewDataSource,and use an NSMutableArray to set the data to cellVC.
How to prfioritize the tableView cells in order to display at the top of tableView in the mothod cellForRowAtIndexPath?
I want to display the priority cells at the top of the tableView cells checking if they have priority or not, depending on the bool value of havePriority property, such that if havePriority is 1, it should be true else should be after the priority list.
I've tried by using different cell identifiers but unable to got the list at the top.
My Code:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (havePriority) // if the cell wants priority to be at top, have a value in bool
{
cell.textLabel = sOmeText; //
NSLog(#"%#",sOmeText);
}
return cell;
You shouldn't be setting the order of the cells in that method. By then it is far too late.
This is really something that should be done in the model layer. The list of items to be displayed should already be sorted according to their priority, and that way they will show up at the top.
Secondarily, this type of code isn't really necessary anymore:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
You should be using the more modern method:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
This will either return a cell from the reuse pool or create a new one, so it always returns a cell, and there is no need to create one yourself.
Hi I have this problem that if I add more than 13 items in my uitableview the items will repeat
this is my code for
Adding:
[categoryList insertObject:inputcategory atIndex:0];
NSIndexPath *indexpath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtindexPaths#[indexpath] withRowAnimation:UITableViewRowAnimationAutomatic];
CellForRow:
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.textlabel.text = [categoryList objectAtIndex:indexPath.row];
}
NumberofRows
return [categoryList count];
the first 12 items are okay but after that it adds the same last object in my NSMutableArray again in my uitableview and when I reload it, It only records 12 items.
In cellForRowAtIndexPath: method change
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.textlabel.text = [categoryList objectAtIndex:indexPath.row];
}
to
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textlabel.text = [categoryList objectAtIndex:indexPath.row];
If you set text in if (cell == nil) it will not updated on reusing the cell. When reusing the cell will not be nil.
Akhilrajtr's answer is correct but is the old way of doing it. In 2014 for iOS 6+ you should instead be using the UITableView methods
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier
or
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
and
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath
Getting a cell in cellForRowAtIndexPath: becomes much simpler...
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
"identifier" is the unique string used to identify cells for reuse, just like the old way.
From Apple's documentation, "This method dequeues an existing cell if one is available or creates a new one based on the class or nib file you previously registered." You don't need to use initWithStyle any more, and if you think you do then consider subclassing UITableViewCell instead to more precisely control the appearance of your cells.
No more checks for the cell being nil are required. Just go ahead and set labels if your cell is a plain UITableViewCell or configure your subclassed cell (which should of course have made itself ready for reuse with the prepareForReuse: method)
Apple mention the performance this in their documentation on UITableViews.
it's should be about Reuse Cells. So if the cell != nil u can't got this below work:
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.textlabel.text = [categoryList objectAtIndex:indexPath.row];
}
Reuse cells. - Object allocation has a performance cost, especially if the allocation has to happen repeatedly over a short period—say, when the user scrolls a table view. If you reuse cells instead of allocating new ones, you greatly enhance table view performance.
I've seen this problem with many others, went thru all the topics, but I can't seem to find a solution for it.
So I have a normal table view, with a cell linked to a .xib file, at first launch everything looks normal, but once I start scroll the app crashes immediately.
By enabling zombie objects I got to this error:
2012-05-03 16:18:13.008 coop_dev[27547:f803] * -[ActivityTableViewController tableView:cellForRowAtIndexPath:]: message sent to deallocated instance 0x6853990
But I'm not sure what to look for or what might go wrong:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
ItemCell *cell = (ItemCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ItemCell" owner:nil options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
Item *item = [self.activity objectAtIndex:indexPath.row];
[[cell projectLabel] setText:item.project];
[[cell descriptionLabel] setText:item.description];
[[cell timeLabel] setText:item.time];
[[cell timeAgoLabel] setText:item.timeAgo];
//cell.avatar = [UIImageView item.avatar];
cell.descriptionLabel.numberOfLines = 0;
[cell.descriptionLabel sizeToFit];
// remove the right arrow
cell.accessoryType = UITableViewCellAccessoryNone;
return cell;
}
It works fine at first launch but after that just crashes
EDIT
I re-created the problem in a new project, just a basic table with some data, once you start scrolling it crashes. Download: http://dl.dropbox.com/u/274185/TestTable.zip
In your FirstViewController.xib, remove the UITableViewController, but leave the UITableView. The crash happens because the File's Owner is already set as class FirstViewController in the Identity Inspector and it's like you have a second UITableViewController. Make sure also that the UITableView is hooked to the view outlet of the controller.
You are dequeueing code is a bit off... try mine:
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell = nil;
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"]
autorelease];
cell.imageView.image = nil;
cell.textLabel.text = nil;
}
Check your ItemCell class' dealloc method, you're probably overreleasing something.
This post is closely related to my previous post: TDBadgedCell keeps caching the BadgeNumber
The "badge" from TDBadgedCell keeps caching the numbers. A very simple example is shown here:
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
TDBadgedCell *cell = (TDBadgedCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
[cell setBadgeColor:[UIColor blackColor]];
[cell setBadgeNumber:[indexPath row]];
[[cell textLabel] setText:[NSString stringWithFormat:%#"%d", [indexPath row]]];
return cell;
}
Anyone has any clue why this happens? The textLabel and detailTextLabel don't cache the data. Any additonal info would be welcome as well, as I seem to have a lot of issues with the caching of graphics in UITableViewCells. Any best practices or other useful information would be most welcome.
OK, I figured this one out. Apparently I shouldn't use the default code to initialize my cell when using the TDBadgedCell. The following code:
TDBadgedCell *cell = (TDBadgedCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
Needs to be changed into this:
TDBadgedCell *cell = [[[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
I am wondering if this is clean in terms of memory usage and such, but it'll do for now at least.
I thought this was fixed in commit 2d255f075fe53ad10afe8eb65666207a8f2c65d0, which was made on March 22, 2013. In my case, this initially seemed to fix the issue most of the time, but I still saw cached badges occasionally. Then I realized that you can fix this once-and-for-all by using two different cells: when you need a badged cell, dequeue a TDBadgedCell, and when you don't need a badge, dequeue an ordinary UITableViewCell.