I have a view controller that manages a table view. My understanding is that a table cell will be deselected automatically if I push another viewcontroller and then pop back to the table view.
However, in the same class (that I use a few times), there is one instance of the class when the cell is deselected but not animated (it'll just turn blue and then back to normal without animating). Why did this happen? I have a few instances of this class but it only happens to one of them. What might be causing this?
From my experience cells are not automatically deselected if you push/pop a view controller (at least not when using a navigationcontroller), unless you add some code te deselect it !
It may also be automatically deselected if you are doing a [tableView reloadData] in viewWill/DidAppear (or in a process started in these methods).
Did you try to add something like that in viewDidAppear ?
NSIndexPath *indexPath = [tableView indexPathForSelectedRow];
if (indexPath != nil) {
[tableView deselectRowAtIndexPath:indexPath animated:YES]
}
NSIndexPath *indexPath = [tableView indexPathForSelectedRow];
if (indexPath != nil) {
[tableView deselectRowAtIndexPath:indexPath animated:YES]
}
this you have to write in didselectRowAtIndexPath method
You can reload the Tableview again.
In your viewWillAppear
[yourTableView reloadData];
Or if you dont want to disturb your Datasource try this
NSArray *array = [yourTableView visibleCells];
for(UITableViewCell *cell in array)
{
cell.selected = NO;
}
Related
I am trying to force selection(highlight) of a UITableViewCell using selectRowAtIndexPath..
For eg,
Lets say i want to always have the first cell in a table view to be highlighted,I apply the following logic in viewDidAppear
[self.tableViewPrompts selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:0];
Works nicely.But when i try to apply the same logic elsewhere in the application the cell is not selected.I even tried deselecting other cells before calling the above method and reloading tableview before and after calling this method but none of the approaches seem to work!
I even used the tableview's delegate to forcibly make a call to the didSelectRowAtIndexPath.Event this does not work.
PS: The selection of the cell does not trigger any action all i am trying to achieve is highlighting the desired cell.
What am i doing wrong here?
Help is greatly appreciated!!
The selection of the cell does not trigger any action all i am trying to achieve is highlighting the desired cell.
Why don't you use the cell's highlighted property?
UITableViewCell *cell = [self cellForRowAtIndexPath: [NSIndexPath indexPathForRow: 0 inSection: 0]];
cell.highlighted = YES;
Cant test it now, but it should work.....
edit
Better yet, of course: change your cellForRowAtIndexPath to do that
-(UITableViewCell) tableView:cellForRowAtIndexPath:
//...
if (indexPath.row == 0 && indexPath.section == 0) cell.highlighted = YES
else cell.highlighted = NO;
//...
return cell;
I'm puzzled why isn't this working in your case. Here is my method I use from several places inside my view controller including viewDidAppear and I see no real difference with what you're doing:
- (void)selectRow1
{
NSIndexPath* idx = [NSIndexPath indexPathForRow:1 inSection:0];
[_table selectRowAtIndexPath:idx animated:NO scrollPosition:UITableViewScrollPositionMiddle];
[self tableView:_table didSelectRowAtIndexPath:idx];
}
_table is my table property variable, and the call to didSelectRowAtIndexPath is made so the action of selection could happen but otherwise the only real difference with your code is the scrollPosition parameter.
Simply use setSelected to highlight cell:
[cell setSelected:YES];
I have created this extension for the whole purpose UITableView-Ext
I am using [self.messageList scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; in cellForRowAtIndexPath and it is working fine, when a row is added in table array then it auto scroll upside but the problem is that when I try to see the top rows then it automatically come again last rows. And I am not able to see my all rows. Please let me know where I use this or any other approach to do this.
cellForRowAtIndexPath method is not called for all cell that you have. It is only called for visible cell in your TableView. When You Scroll UITableView then it ask to UITableView that you want to use reusable cell or add to new one. generally we use reusable cell so, it is use 1st no of cell and add at end of cell . it is not create another new cell at the end. so, when you scroll your UITableView it not scroll to end of cell it indexPath is similar to indexPath of first no of cell. so you can not scroll your UITableView at to Down.
use following code may be helpful for you.... :)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
[self.tblView scrollToRowAtIndexPath:indexPath atScrollPosition: UITableViewScrollPositionTop animated: YES];
// your code
}
// your code
return cell;
}
If you write this code in your cell for row at index path, then it will get called every time you try to scroll manually coz this message is called to draw your cell and you will b directed to the row you specified. Try checking your indexpath in a IF--Else block and scroll only when a certain action happens.
cellForRowAtIndexPath is a method for creating a cell to view .When you scroll this method is called when a cell is viewed.So each time the method called the [self.messageList scrollToRowAtIndexPath:indexPath method(which is called inside cellForRow) is also called and the table scrolls down to that row!!!
I am about to go out of my mind here, in my Core Data databse I have a lot of users, i have hooked the database up to a tableviewcontroller via NSFetchedResultController, and when the view loads, I see all my users, and i can perform a push to a detail viewcontroller via storyboard segue... so far so god, my tableview contains a custom cell with an image view and 2 uitextlabels that all has their tag values assigned..
Now, when I perform the search I create a new NSFetchedResultController with a predicate, and performs the performFetch.. I then get the fetchedObjects property and it contains the users that match, so the search request is also working like a charm.. in all my tableviews datasources I check if self.tableView == self.searchdispl.view to see which controller I should query data from.. In all the controllers delegates I check to see which controller is active so i know which view to reload. If i nslog a lot of data it is all fine behind the scenes, the delegate and datasource methods all use the correct view and fetchcontroller..
In my cellForRowAtIndexPath i can log out my user.name, and that is always correct, also when searching.
The issue is that the UISearchDisplayController view that is on top only has empty cells, unless i set my UITableViewControllers dynamic prototype cell to basic, then both tableviews contain that label with the users name ! The segue from the cell still doesn't work, but there is data in the cell.
It seems as the UISearchDisplayControllers view is a generic view, at least when it comes to segues and cell layout...
I have checked all the connections from the UISearchDisplayController to my UITableViewController, and all looks fine...
Why will the SearchDisplayControllers view not accept my cell layout and segue ?
Thank you :)
Update : has just figured out what is going wrong, but not found the solution yet.
In my cellForRowAtIndexPath the cell is always configured as the Default Cell when thr searchdisplayview is in this method.. Do i really need to create my cell in code for the uisearchdisplay to work ? Why can it not use the configured cell from the storyboard ?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"PersonCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"Default Cell");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSFetchedResultsController *controller = tableView == self.tableView ? self.fetchedResultsController : self.fetchedResultsControllerForSearch;
Person *p;
p = [controller objectAtIndexPath:indexPath];
[(UILabel*) [cell viewWithTag:1] setText:p.name];
[(UILabel*) [cell viewWithTag:2] setText:#"Status"];
if(p.avatarImage){
UIImage *avatar = [[UIImage alloc] initWithData:p.avatarImage];
[(UIImageView *) [cell viewWithTag:3] setImage:avatar];
}
return cell;
}
The issue was that when i got the cell in cellforrowatindexpath, it didn't get it from the original viewcontrollers tableview, so i changed the line from
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
to
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
and now all is good, the cell has the layout from storyboard and segues works like a charm..
I have multiple UITableViews in my app, is there a method of detecting which cell/row the user has selected in that column?
Also is it possible to programatically deselect a cell/row?
Thanks.
Get currently selected index path for a table:
NSIndexPath *path = [tableView indexPathForSelectedRow];
Deselect currently selected row:
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
These are all easily found in the documentation for UITableView. Perhaps you should look there first next time.
Here's even a link: http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html
NSIndexPath *path = [tableView indexPathForSelectedRow];
The above line will throw EXC BAD ACCESS if no sell is selected so keep track of your selected cell with NSIndexPath instance variable and only deselect when it is actually selected with isSelected property of cell.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:someIndexPath];
if(cell.isSelected) {
[tableView deselectRowAtIndexPath:someIndexPath animated:YES];
}
I have a UISplitViewController with a Table View for navigation. It's similar to the Mail app. When you click on a table view in portrait mode, the popup hides itself. When you click on the nav bar to get the popup back, the selected item no longer appears selected. How can make this item appear selected without re-selecting the item? (just like in the mail app)
In your viewDidLoad method, do you call
self.clearsSelectionOnViewWillAppear = NO; ?
This is how Xcode's SplitView template does it.
Do you have by any change a
[tableView deselectRowAtIndexPath:indexPath animated:YES];
in your didSelectRowAtIndexPath in the RootViewController ?
I've got a solution that works, but it's frustratingly hacky. I have to call selectRowAtIndexPath twice. It seems that cellForRowAtIndexPath is invalidating the selection made in viewWillAppear. It still needs to be called in viewDidAppear, however, so the view scrolls to the proper position before cellForRowAtIndexPath is called.
- (void)viewWillDisappear:(BOOL)animated
{
NSIndexPath *selected = [self.tableView indexPathForSelectedRow];
_selectedRow = selected.row;
}
- (void)viewDidAppear:(BOOL)animated
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_selectedRow inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//initialize cell code here...
if (indexPath.row == _selectedRow) {
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}
}
For your table view controller, is -viewWillAppear: called before the pop-up is displayed? If so, you could write it as so:
- (void)viewWillAppear:(BOOL)animated
{
[self.tableView selectRowAtIndexPath:<indexPath>
animated:animated
scrollPosition:UITableViewScrollPositionMiddle];
[super viewWillAppear:animated];
}
Obviously, replace <indexPath> with the proper index path and set the scroll position how you want it. You may also want to pass NO instead of animated to make it appear like it was selectd before the view appeared.