deselectRowAtIndexPath - Was it needed? - ios

I was following this tutorial: https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/ThirdTutorial.html#//apple_ref/doc/uid/TP40011343-CH10-SW1,
where you have a table view.
The table view has Dynamic prototype cells.
During the tutorial, I selected a cell on storyboard, and set the 'Selection' type to: none.
But in the final part of the tutorial, still we were told to add
[tableView deselectRowAtIndexPath:indexPath animated:NO];
line inside the
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
method.
For me this seemed redundant, due to the 'Selection´ is none which I did as above.
Or I am wrong? Since I selected none as Selection in storyboard(for a cell), why do we need that deselect method? The cell won't be higlighted anyway, isn't it?

The row is still selected. The style of 'none' only relates to how it looks when selected.
So yes, you need to deselect the row when you are done with it.

Changing the "Selection" setting in storyboard changes the way that the cell looks when selected. (Thank you rmaddy, that was my mistake)
The line in didSelectRowAtIndexPath will perform some operation when a specific row is tapped, and then removes the selected graphic from the cell that was just tapped.

Related

Handle deselect row in table view

I want to handle case when user deselect row (that already selected) by tap on this row. It is well known that tableView:willDeselectRowAtIndexPath: / tableView:didDeselectRowAtIndexPath: delegate methods not called in this case: they are called only if you tap on other, unselected yet row (my table view have single selection mode).
tableView:didSelectRowAtIndexPath: method also not called when I am deselecting row.
Is there is any easy solutions?
Update
The problem was in tableView:willSelectRowAtIndexPath: method, where I return nil in some cases, thats why tableView:didSelectRowAtIndexPath: didn't call. Thanks #Nekto for useful information and helping.
Apple docs say next about - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
This method isn’t called when the editing property of the table is set to YES (that is, the table view is in editing mode).
That means that this method should be called unless your code has a bug or you haven't updated delegate of your table view or table is in editing mode.
One of the possible problems could be that you have incorrectly implemented - (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath and are returning nil for the selected row. In that case didSelect... isn't called:
Return nil if you don’t want the row deselected.
Alternatively you can implement another table view delegate method: - (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath:
Tells the delegate that the highlight was removed from the row at the specified index path.
See more about managing selections in table views here.
You can still use tableView:didSelectRowAtIndexPath, just use it like a check mark system would work.
The answer here explains how to use a checkmark. You can use this, or use the answer here.
I have such use case. Why you don't create a variable for lastSelectedRow(here I have problem if it was NSIndexPath and I used two integers) and on the method for selecting row just compare currentSelectedRow with lastSelectedRow.

Objective-C: Set another UITableViewCell on select

I have two custom models of TableViewCell, one for just basic informations and another for detailed informations.
How can I switch to the detailed one with the didSelectRowAtIndexPath method? (and afterwards if the detailed one is displayed, toggle to the basic one on select)
Thank you.
When the row is selected, toggle a flag indicating that the row needs to switch from one type of cell to another. Then reload the the cell at that index path.
Then your cellForRowAtIndexPath method looks at the flag for the given index path and returns one of the two types of cells.
In whatever kind of object you use to represent cell data, keep a flag for whether it's selected or not. Turn the flag on or off in didSelectRowAtIndexPath and then reload the table view data. When you return a cell for an index path, choose which kind of cell based on the flag value.
You can create an array or set consist of indexPaths of cells type 1. Add or remove from it cells if needed. Return the right cell in
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
And if you want to reload specific cell, modify your array of cells and just call from tableView:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths
withRowAnimation:(UITableViewRowAnimation)animation

Refreshing the view of UITableView

I understand the concepts of cell re-usability for Xcode 5.0 table views. However, I have one very weird observation which I don't understand and wish anyone of you could enlighten me here. Thanks.
I have implemented a table view with a search bar utility (just on top of the table view). Under each custom cell (prototype cell), whenever a user clicks on it, it will be marked with a checkmark (UITableViewCellAccessoryCheckmark). The number of cells are more than 10.
Observation:
- Without using any search, marking and unmarking a cell is working as intended. Cells are updated instantly along with their checkmarks.
- When doing a search, from the results given, marking and unmarking a cell is also working as intended.
[Problem] Here comes the weird issue: when cancelling a search, an already marked cell (marked during search) does not refresh itself in the tableview unless scrolling up or down is performed!
And hence, I wrote [tableview reload] at the end of tableview:didSelectRowAtIndexPath: method. Obviously, it doesn't refresh the tableview for me. Without further changing any other code, merely modifying [tableview reload] to [self.tableview reload] under the same method works!
Why is the only addition of "self." able to make the table cells refreshed instantly? I have always thought the first argument, tableView, from the method (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath is as equal to self.tableview. Obviously, my interpretation in this case is wrong.
Thank you. I'm sorry for my lengthy post.
My guess is that this UISearchBar comes from a UISearchDisplayController. Is that correct?
If true, that is a common misconception, but an easy one to understand.
When filtering your UITableView entries and showing results, UISearchDisplayController actually overlays the view with its own tableView, UISearchResultsTableView.
Thus, this overlaid tableView also gets to call data source and delegate methods on your implementation, and this is when the tableView argument from tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath stops being equivalent to self.tableView.
This means that calling [tableView reloadData] during filtering actually asks UISearchResultsTableView to reload its contents, not self.tableView, a property of your viewController.

iOS - How to display the same table view after selecting an item

My iOS app is current transferring control to a detail view when an item in a UITableView is selected. This ia a quiz program, and I'd like to change the app so that it just redisplays the same table view with the correct answer highlighted when a row is selected. What's a good approach for doing this?
Is not clear to me if you know why the detail view is appearing. So I'll explain just in case. If you are giving control to a detail view is because somewhere in your code you are pushing that detail view. It depends on what kind of UITableViewCell you are using. If you are using one of the defaults styles, your detail view is probably been pushed in either:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
or
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
If you are using a custom cell, then you need to look for the method in charge of pushing
that detail view.
I think a good approach would be to:
Remove that pushing wherever it is.
Not to use an `UITableViewCellAccessoryType, if you are using one.
Do something similar to the following on your tableView:didSelectRowAtIndexPath:
Find the row for the right answer in your model array, according to tapped cell.
Use that row number to generate an NSIndexPath.
Use that NSIndexPath to find the correct cell with cellForRowAtIndexPath:
Call setSelected:animated: on that cell to highlight it.
NOTE: If your quiz has more answers than the amount of UITableViewCells that fit in the screen you should scroll your UITableView to the right answer for better UX.

Grouped TableView selection problem

Ok, I have a grouped TableView that has the following overridden method:
-(NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
return nil;
}
... Obvious enough, to disable selection.
BUT!
If the user presses and holds on a cell, it gets highlighted (selected)!! I need to disable this, too.
On a side note, I am using the tableView to display static Data, almost like the About tableView in Settings > General. It just loads the info from an array of strings that I created manually.
If there is a better way to represent the data, please do tell!
Thanks!
Set the selectionStyle property of the cell to UITableViewCellSelectionStyleNone.
See the documentation for tableView:willSelectRowAtIndexPath: to see why this is needed even though you're indicating that you don't want the cell selected.
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
...did the trick.

Resources