iPhone/iPad SimpleTableViewCells: What replaces the deprecated setImage setText on table cells?
The below code gives warnings that setImage and setText are deprecated. So what replaced them? What is the new better way to get this simple behavior?
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier: SimpleTableIdentifier] autorelease];
}
cell.image=[UIImage imageNamed:#"Wazoo.png"];;
cell.text = #"Wazoo";
So what is the simplest way to have the same affect as image/text of a cell without doing a lot of work or getting warnings?
With new release of iOS SDK, setText and setImage properties are deprecated and they are replaced by textLabel.text for setText and imageView.image for setImage...
With this new properties, your code would be:
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier: SimpleTableIdentifier] autorelease];
}
cell.imageView.image = [UIImage imageNamed:#"Wazoo.png"];;
cell.textLabel.text = #"Wazoo";
This properties are usually used when the cell uses preimpostated styles like UITableViewCellStyleDefault, UITableViewCellStyleSubtitle, UITableViewCellStyleValue1 and UITableViewCellStyleValue2 or CGRect...
If you will display also a subtitle, the code to be used is:
cell.detailTextLabel.text = #"Your Subtitle Here!";
You call textLabel.text and imageView.image on the cell.
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier: SimpleTableIdentifier] autorelease];
}
cell.imageView.image=[UIImage imageNamed:#"Wazoo.png"];;
cell.textLabel.text = #"Wazoo";
Related
Does this code triggers when I call [Self.table reloadData]
if (cell == nil){...}
Im wondering because I have added a UITextField in the cell:
//cellForRowAtIndexPath
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
recepientTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.contentView.frame.origin.x+40, 10, 469, 20)];
[cell addSubview:recepientTextField];
}
recepientTextField.text = recipient;
return cell;
Then I download some stuff from internet and I then want to show the info in recepientTextField.text in the TableView. So I call set a new value to recipient variable and then [self.tableView realoadData] But it crashes. I think it has to do with the textfields allocation. How can I fix this? How can I change the text afterwards?
When reloaded the cell != nil case comes and there the recipientTextField has null reference and hence the crash
Try this
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
recepientTextField = [[UITextField alloc] initWithFrame:CGRectMake(cell.contentView.frame.origin.x+40, 10, 469, 20)];
[recepientTextField setTag:333];
[cell addSubview:recepientTextField];
}
UITextField *TF=(UITextField *)[cell viewWithTag:333];
TF.text = recipient;
return cell;
When I write a simple code to create a table, I got _CGRect referenced From error. I don't know how to solve this error. I even added the CoreGraphics framework into my project
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier: SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.text = [listData objectAtIndex:row];
return cell;
try
CGRectMake(0,0,widthOfCell,heightOfCell)
in your
cell initWithFrame
method, i think tht should do it for you.
Can anyone please tell me what is the correct way to manage UITableView if I have a big number of cells? The interface of each cell depends on sections (each cell keeps different UI elements in its content view). I do not want to use reusable cells as it messes up with overlapping.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault nil] autorelease];
} else {
cell = nil;
[cell release];
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault nil] autorelease];
}
No, your code is not correct. First of all, it wouldn't even compile because [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault nil] is not valid syntax. Secondly, the [cell release]; line has no effect (which is good because if it had, it would be wrong) but its presence shows that you haven't understood the memory management concepts (yet).
Thirdly and most importantly, you should definitely use the table view's cell reuse, especially if you have a big table. If you have different types of cells, just use different reuse identifiers for them, no problem. The table view will then create multiple reuse pools and always return a cell of the type you ask it for in dequeueReusableCellWithIdentifier:.
I'm using reusable cells in my app. The method I'm using is as follows:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [yourArray objectAtIndex:row];
return cell;
}
It works fine.
Without reuseIdentfier you will run out of memory fast and tableview will scroll slow. You should change content of cells in this method, e.g. titles, images, etc. but not views. So create subclasses of cell for every section you need. Setup their views and in this method setup content.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
} else {
cell.title = [_cellTitles objectAtIndex:indexPath.row];
cell.image = [_cellImages objectAtIndex:indexPath.section];
}
I have a list of cells in a table view where only the last cell has a disclosure indicator (it triggers an action). When I scroll down my list of cells everything works fine, but if I scroll back up oddly the disclosure indicator appears in other cells too. I can't really figure out where's the problem, any help?
Thanks,
Daniele
This is the part of code that is use:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
if(([myArray count]-1) == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
that is not a bug: it is a feature ;) because the cells are being reused.
If your tableview contains 200 cells and your iphone is able to show 5 cells at the same time then you only have 5-6 instances of UITableViewCell. If you scroll down a cell gets the disclosure-button and if you scroll back the cell is being reused and as a result the disclosure-button is still there.
to solve your problem:
approach 1: not only set the disclosure-button on the last cell. you should also remove/unset it in other cells.
approach 2: it seems that the last cell is another type of cell in semantic. So choose a reuse-identifier for example: #"MyLastCell for the last cell and #"MyCell" for all other cells. As a result your tableview will only reuse cells of the same type (in your case: with/without disclosure-button)
edit 1: some sample-pseudo-code for approach 2 ;
edit 3: shorter solution for approach 2
static NSString *CellIdentifier = #"Cell";
static NSString *LastCellIdentifier = #"LastCell";
bool isLastRow = (indexPath.row == numRows-1);
NSString *usedCellIdentifier = isLastRow ? LastCellIdentifier : CellIdentifier;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: usedCellIdentifier];
if(!cell)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:usedCellIdentifier] autorelease];
if(isLastCell)
{
//do disclosure-stuff here. Or add a UIButton here
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton
}
}
edit 2: sample code for approach 1
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.accessoryType = (idexPath.row == numRows-1) ?
UITableViewCellAccessoryDetailDisclosureButton
: UITableViewCellAccessoryNone ;
As thomas said, you can use his code and you can add this:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
for the last cell (inside the if where you dequeue your last cell) and this:
cell.accessoryType = UITableViewCellAccessoryNone;
for other cells (inside the if where you dequeue other cells).
I haven't tried this code but it should work... ;)
try this
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
if(([myArray count]-1) == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
I am getting a really strange error and I can't figure out how to fix it: When I scroll around in my UITableView it will sometimes highlight a cell blue, even when I don't fully selected.
For example:
-Cell 1-
-Cell 2-
-Cell 3-
-Cell 4-
If I put my finger down on Cell 2 and scroll to Cell 4 it will leave Cell 2 highlighted, even though didSelectRowAtIndexPath: is never fired.
Any ideas?
EDIT
Added code:
UITableViewCell *cell = nil;
static NSString *cellId = #"StyleDefault";
cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId] autorelease];
}
cell.textLabel.text = #"Cell One";
cell.textLabel.textAlignment = UITextAlignmentCenter;
[cell setAccessoryView:nil];
return cell;
FIXED IT!
My solution was two parts:
1) In cellForRowAtIndexPath: put "cell.selected = NO;", which fixes the problem of if the cell gets touched down on then goes off screen (scrolling).
UITableViewCell *cell = nil;
static NSString *cellId = #"StyleDefault";
cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId] autorelease];
}
cell.textLabel.text = #"Cell One";
cell.textLabel.textAlignment = UITextAlignmentCenter;
[cell setAccessoryView:nil];
//Here:
cell.selected = NO;
return cell;
2) Put "[tableView deselectRowAtIndexPath:indexPath animated:YES];" into didSelectRowAtIndexPath: instead of what I used to have "[[tableView cellForRowAtIndexPath:indexPath] setSelected:NO];" which was wrong on so many levels.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Hopefully that helps others that have this issue. Case closed.
You can use following while creating cell.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = Your allocation.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
I guess you need to also please have look at the UIViewTable Property for Touch i.e. Delay Content Touches and Cancellable Content Touches.
Hope this helps.
Override -tableView:willSelectRowAtIndexPath: in your UITableView delegate, and return nil for everything just to make sure you're not allowing it to select the rows.