Have UITableView row selected rather than just highlighted - ipad

I currently set the selected row of a UITable via
selectRowAtIndexPath:animated:scrollPosition:
and as described in the documentation, this does not call
tableView:didSelectRowAtIndexPath:
so I have set up a selector call to perform this action.
However, the end result is that the row in the table is highlighted, but not selected. When I touch the highlighted row, the font color changes to white.
Is there a way to not only highlight, but also have the row "selected" so tapping that row again does not result in any changes or updates?

Try calling didSelectRowAtIndexPath directly and then scrolling to it. I have this in a UITableViewController and it works fine (and the selection event does not fire again when you tap on it, I just tested it). I'm wondering if there is some other code messing you up.
[self tableView:self.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];

Related

How to update a UITableView so that UITextField in a cell won't lose focus

The setup: The table has 1 custom cell. This cell has 1 text box. In each text box a number is entered. The tableView has 5 rows (of this cell). If I change one number in any of the cells, then all the cells need to be updated, I simply call tableView.reloadData(). The change in the text box is handled with the editingDidEnd event.
The problem: I click any of the textFields and change the number. Then, I click another textField to change its value. first editingDidEnd is called, all the values are re-calculated, and tableView.reloadData is called. Now, the click to the second textField is missed because the table is reloaded.
I am not able to update the cells directly because they are custom cells and the value is changed within that class. I cannot update ALL the cells from custom cell class.
A difficult question to explain in writing especially for a non native English speaker. If you understand the question, any pointers will be appreciated :).
Using Xcode 7.1 and Swift. Thank you.
When you call reloadData, all the cells are removed from the tableview and re-added. Since it is removed, it is no longer in the responder chain meaning its text field can't be the firstResponder (selected).
There are two options that could work.
Keep track of the row that is selected, call reloadData then call becomeFirstResponder on the text field for the correct row.
Not call reload data and just update the values in the text fields. This option more depends on the striation of your app.
This can be quite simple, ideally you are in a position to store the values for the field you want to focus and the index path of the cell in question (such as when you regenerate the editing field after your reload?)
This code should help:
- (void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath == self.editingIndexPath)
{
[self.editingTextField becomeFirstResponder];
}
}

Disable user interaction when didSelectRowIndexPathRow is called

So when the user selects a row, I put the selection on another thread for performance reasons. When I take it off of the main thread, the row is deselected for a few seconds and the pushed to the next view. Those few seconds when the row is deselected and taken off of the main thread, the user has the option to rapidly click the row again, and again - forcing the app to potentially crash. So my question is how would I deselect user interaction on the table row inside of the didSelectRowAtIndexPath method? Now, please acknowledge I don't want to disable user interaction before the a row is selected. I only am looking to disable user interaction on the cell after the row has been selected. Thanks!
Make an instance variable NSIndexPath selectedPath;
Add
[[self.tableView cellForRowAtIndexPath:indexPath] setUserInteractionEnabled:NO];
selectedPath = indexPath;
to your didSelectRowAtIndexPath and in performSegueWithIdentifier (assuming you are using storyboards) add
[[self.tableView cellForRowAtIndexPath:self.selectedPath] setUserInteractionEnabled:YES];

Keep UIKeyboard up while reloading UITableView section

I would like to know if there is a way to keep UIKeyboard up while reloading section in UITableView? I have UITextField inside a header view of UITableView's section. Typing into this UITextField fires action that requires a section to be updated (reloaded).
As a result of calling [tableView reloadSections:...] the keyboard hides itself, because UITextField loses it's firstResponder status.
I would like to achieve similar effect like when using UISearchBar component in UITableView.
Thanks!
If you reload, everything will get refreshed. When that happens, the current first responder is resigned and the keyboard is animated out. To avoid that you need to no reload...
You would need to update the visible cells directly and use insertRowsAtIndexPaths:withRowAnimation: and deleteRowsAtIndexPaths:withRowAnimation: to make changes to the number of rows the table is managing. In this way the section won't be reloaded and you will avoid any cell animations / refreshing of views.

tableView:didDeselectRowAtIndexPath: not called until first user-initiated selection and deselection

I have a UITableView with four cells, in single selection mode. When the view is first loaded, I programmatically select one of the cells using -selectRowAtIndexPath:animated:scrollPosition: based on a stored preference. After this, the user can interact with the table.
The methods -tableView:willSelectRowAtIndexPath: and -tableView:didSelectRowAtIndexPath: are called on my table view delegate every time the user taps any cell. However, -tableView:willDeselectRowAtIndexPath: and -tableView:didDeselectRowAtIndexPath: (that's DEselect) don't start being called until the user manually taps that first programmatically selected cell.
Any idea why this might be happening? Are there any workarounds besides manually calling -[UITableView selectRowAtIndexPath:animated:] for every cell except the one that the user tapped?
If you do invoke [UITableView selectRowAtIndexPath:animated:] too soon and you are using a UITableViewController, you probably have conflict with the UIViewController clearsSelectionOnViewWillAppear (defaults to YES). Try setting self.clearsSelectionOnViewWillAppear = NO; in your viewDidLoad
This is too long for comment so I'm posting this as an answer.
Just created test project with tableView. I call [UITableView selectRowAtIndexPath:animated:] on viewDidLoad and I have one cell selected. Then I'm selecting another cell (without deselecting first one).
I have this output:
[SDTVTViewController tableView:willSelectRowAtIndexPath:]
[SDTVTViewController tableView:willDeselectRowAtIndexPath:]
[SDTVTViewController tableView:didDeselectRowAtIndexPath:]
[SDTVTViewController tableView:didSelectRowAtIndexPath:]
And I have first cell deselected and second one selected.
I have no idea, why it's not working in your code. When you're calling [UITableView selectRowAtIndexPath:animated:] and can you post code of UITableViewDelegate methods that you've implemented?
I was wrapping my initial data source updates and -selectRowAtIndexPath:... calls in
[_tableView beginUpdates];
// ...
[_tableView endUpdates];
Apparently, like -reloadData, this clears the current selection (not sure if that's by design). I moved the call to -selectRowAtIndexPath:... to after -endUpdates and now everything works as intended.

UIPickerView in UITableViewCell - how to select values instead of scrolling TableView?

I've got a custom UITableViewCell that has a label and a UIPickerView. Display works fine, but when I want to select a value in the Picker, the TableView scrolls. What can I do so that the gestures in the cell go to the Picker instead of the whole TableView?
The only solution I could come up with was to set the whole TableView to scrollEnabled = NO. This works for the Picker, but now I can't get to the cells under the custom cell. Control has to be more fine-grained.
If you can get hold of the UIGestureRecognizer for each of the two gestures, and tell one it needs to wait for the other to fail. With one in every cell, that becomes over-wieldy.
Perhaps you should add a control or have the accessory view "bring up" the picker, and then dismiss it when done.

Resources