I have a tableview called allone.h with cells that are all subtitle style cells with a disclosure indicator.
The subtitle text is generated dynamically, so it's pretty likely each cell will have different subtitle text.
I have an if statement that says if the text = "hello, world", then change accessory type to detailDisclosureIndicator. When the detailDisclosureIndicator is pressed, it pushes a new controller, changes the subtitle text, then pops that view controller and returns to allone.h. The problem is, it still shows the detailDisclosureIndicator even if the text != "hello, world". I tried changing the style in viewWillAppear, but I don't have access to cell.
Here is my code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//populate cells with stuff
if([cell.detailTextLabel.text isEqualToString:#"hello, world"]){
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
}
So I guess my question is, how do I change the accessory type back once I return to allone.h and the cell's text is no longer "hello, world"?
You can do that in your -[UITableView cellForRowAtIndexPath:]. Just like an "else" for your if statement.
And to reload the cell, you can just call reloadData or reloadRowsAtIndexPaths:withRowAnimation:.
I think cell.detailTextLable is equal to nil. So cell accessory doesn't change. Please double check it. did you configure the cell before?
Related
I changed the color of text for the cell clicked in the table. But after the cell is clicked, when i come back to table the text of cell has the original color. Could you give me an advice?
This is the code in "didSelectRowAtIndexPath"
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.highlightedTextColor = [UIColor blueColor];
Thank you
after the cell is clicked, when i come back to table the text of cell has the original color. Could you give me an advice?
You need to have the color for each cell stored somewhere other than in the table, so that you can reproduce the colors you want anytime the table redraws itself. Typically, you'll have some sort of data structure that stores the table's data, and that's usually the right place to save any changes the user makes. The table view's data source should have a -tableView:cellForRowAtIndexPath: method that sets the color according to what you've saved, along with any other cell attributes.
This is happen because the cells are reused, so lets say when you change text colour property of some cell it will be affected as you expect but when you scroll and that cell disappear off the screen it will be put to reuse pool and if it appears again on the screen table view takes some cell from the reuse pool but it's properties will be different so the colour won't persist.
You should keep somewhere, for example in NSMutableArray, info about which table was clicked.
You can add an index path to the array when you click the cell and in cellForRowAtIndexPath: check is this indexPath in the array and if it is change appropriate property.
The problem is that iOS throws away your cell if you scroll away and recreates it when it's needed (you scroll back to the cell).
If I were you, I would subclass UITableViewCell and overwrite
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
In there you would have
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected: selected animated: animated];
self.textLabel.textColor = selected ? [UIColor blueColor] : [UIColor blackColor];
}
Since iOS UITableView remembers which cell is selected, this should work fine, even when it's recreated.
The reason it's happening is what others are saying: cells are reused.
Storing selection state or color will work, however if you just need to make sure that selected cells have a different color for a label than non-selected cells, there's a way that does not require to use a supporting data structure.
You just need to check if the cell being setup at - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath is currently selected or not, and that can be achieved with [tableView indexPathForSelectedRow] if your table uses single selection, or [tableView indexPathsForSelectedRows] if it uses multiple selection.
The last case requires you to find the current indexPath in the returned array, and might be slower than using the supporting array.
But if the selection is simple, then this solution is probably faster, uses less memory and is easier to read (IMO).
In my iOS 7.0 App:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
// AttemptCell is a prototype cell, currently using the "Right Detail" preset
// style and the little information accessory.
static NSString *CellIdentifier = #"AttemptCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
assert(cell != Nil);
if (cell.contentView.subviews.count == 2)
{
UILabel *attemptLabel = (UILabel*)cell.contentView.subviews[0];
attemptLabel.text = attempt.attempt;
UILabel *analysisLabel = (UILabel*)cell.contentView.subviews[1];
analysisLabel.text = [attempt analysis];
cell.tag = indexPath.row;
}
else
{
// Something has gone very wrong.
UILabel *attemptLabel = (UILabel*)cell.contentView.subviews[0];
attemptLabel.text = #"Error";
}
The question is why does the (UILabel*)cell.contentView.subviews[1] sometimes disappear causing the error block to be entered.
This table view shows one custom keyboard entry cell (UITextField) which always appears last. The keyboard entry cell is also prototyped, but with a different dequeue cell identifier. The problem is randomly seen when the keyboard pops up and is closed. Keyboard popping up causes some AttemptCells to go out of view and closing the keyboard causes the AttemptCells to come back into view.
What you are doing is wrong. Don't rely on the view hierarchy of a private class, certainly don't depend on the number of views in a hierarchy and really don't depend on a view being in a certain position of the sub views array. Your error block may not be entered because a sub view has "disappeared" - an extra view could have been added, all you're checking for is that the count of the sub views is equal to 2.
If you're using one of the standard cell layouts, use the textLabel and detailTextLabel properties. If you're using a subclass, use outlets.
I have read many posts about similar problems but nothing seems to work, I am obviously doing something wrong. I have a TableViewController that is in a StoryBoard (XCode 5). For the PrototypeCell I set the type to custom and set the Identifier to "pbvcell". I added some labels, changed the background etc.. Here is my tableview delegate method for setting the cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"pbvcell"];
// Configure the cell...
PBVlead *lead = [self.leads objectAtIndex:indexPath.row];
NSLog(#"Cell class %#", [cell class]);
UILabel *leadNameLabel = (UILabel *)[cell viewWithTag:1];
leadNameLabel.text = lead.leadName;
return cell;
}
Now the app launches but even after I add an object to the tableview datasource array and do a reload data, the cells are blank, like the custom cell is not being used. It looks like this should be easy and thats all I need to do. What on earth am I missing?
I left this in a comment above but just to keep things tidy I will post it as an answer here. It is silly but it is good to note that you have to manipulate the contextView of a prototype cell and not the tableview cell itself in order for your visual changes to have an effect...
"Because I embrace my own stupidity I will tell everyone what was going on here. I had set the TableCell background to blue and added some UILabels and set there color to white to show up against the blue background. Run the app, no labels.... What I finally realized is, I had not set the Content View background to blue. So..... What was happening was the labels actually are shown in the content view in the view hierarchy. White labels on a white background equals, invisible... :-) I set the content view background to blue and wola, there is everything! :-) Brother..?
It's My first time to post a question, thank you for you all in advanced.
Now, i want to implement a default style grouped UITableView contains multiple group of data. for each row, there will be a detail Disclosure button as accessoryType icon. when people click on the disclosure button, i want the Cell expand with detail info for the selected row.
i was trying to fulfill this task by add a customized cell to selected row, however, it was very complex. So currently, i am trying to finish this task by reload a specific row with Customized cell xib. i knew there is a delegate method for reloadRowsAtIndexPaths. but can i use this to reload a specific cell? Thanks
please suggest!
Great Thanks
Have you tried something like this:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == mySpecialSelectedCell)
{
//Load all your custom stuff here
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
}
if (cell == nil)
{
}
return cell;
}
You would have to get the cell's indexPath when you click the expand button.
Or you could look at this answer. And then, like the code above, just load that one cell that you have specified with that NIB and load the rest the way you would normally.
You can implement the tableview delegate methods to set the height for the cell which needs to expand. Add some condition check in heightForRow method and when user taps on button, change the condition to increase the height. When table is reloading it will call this method and will reload cell with bigger height.
I have a UITableViewController with UITextfield inside the tableview cells. If I scroll the table view, the user entered data in the textfields disappears. I tried to add the textfield data to a NSMutableArray but it still didn't work. Any help please.
When cellForRowAtIndexPath: is called, the cell you return has to be completely filled in with whatever data you want to show. So, if the cell includes a UITextfield, you'll need to set it's text property to the right value for that row in your data.
When a table cell disappears off the top or bottom of the screen, the UITableViewCell itself becomes available for re-use. (As you scroll, cells disappear, and new cells appear, but the UITableView class is re-using the UITableViewCell objects.) In cellForRowAtIndexPath: when you get a cached cell to use, you have to be sure to setup everything you want it to show for the row in question, otherwise you might see some odd behavior in your table.
Does this help?
EDIT:
Here's an example of the typical pattern used in cellForRowAtIndexPath:. Notice the use of dequeueReusableCellWithIdentifier:. That method returns a previously allocated but not in use UITableViewCell, if there is one. Notice further that if no cached cell is returned, the code creates a new one, and sets it up (with stuff that is independent of anything that might be row specific). Following that, you'd setup the cell as you need it for the row in question.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SearchResultsCellIdentifier = #"SearchResultsCellIdentifer";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:SearchResultsCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:SearchResultsCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Your row-specific setup of the cell here
// ...
return cell;
}
Check the docs for specifics about these methods. There are LOTS of examples from Apple and elsewhere about how to implement tableViews.