Reputation: 1007
So I have a UITableView
, where all cells have a UITextField
in them as a subview with a tag=1
. What's troubling me is that I want when a user clicks on a textField and edits it to know on which row has that happened. What I think can solve it, is to make the cell select itself when the subview (UITextField
) is selected. How can I achieve that?
I tried with an array, but because cells are reused, it wouldn't work. Looping through all of the rows would be simply too slow.
Upvotes: 2
Views: 1355
Reputation: 11
Disable the UITextField
in each of your cells by default and use your UITableView
delegate method didSelectRowAtIndexPath:
to
UITextField
UITextField
first responderDefine the property in your class extension:
@interface MyTableViewController ()
@property (strong, nonatomic) NSIndexPath *activeIndex;
@end
In your implementation of didSelectRowAtIndexPath:
:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.activeIndex = indexPath;
AddCell *selectedCell = (AddCell *)[self.tableView cellForRowAtIndexPath:indexPath];
[selectedCell.textField setEnabled:YES];
[selectedCell.textField becomeFirstResponder];
}
You'll want to disable the UITextField
again when it resigns its first responder status.
Assuming your UITableViewController
is the delegate for each UITextField
, you can do this in your implementation of the UITextFieldDelegate
method:
-(void)textFieldDidEndEditing:(UITextField *)textField
{
[textField setEnabled:NO];
}
Upvotes: 2
Reputation: 90117
The correct approach is to convert the textFields bounds so it is relative to the tableView, and then use the origin of this rect to get the indexPath.
CGRect rect = [self.tableView convertRect:textField.bounds fromView:textField];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rect.origin];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
Upvotes: 1
Reputation: 152
Code below will return NSIndexPath.This can be written in UITextField delegate -
[tableView indexPathForRowAtPoint:textField.superview.superview.frame.origin];
Try above line your code.
Upvotes: 0
Reputation: 11006
Use the UITextFieldDelegate
to know when the user start editing a UITextField
(with textFieldDidBeginEditing:
).
Two solutions then:
Solution 1: Subclass your cell and make it the delegate of the UITextField
.
Then in textFieldDidBeginEditing:
of your custom cell, make the cell selected:
// MyCustomCell.m
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self setSelected:YES animated:YES];
}
Solution 2: Make the view controller the UITextField
delegate, and select the right cell from there.
// MyTableViewController.m
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
// Find the cell containing our UITextField
UIView *cell = textField.superview;
while (![cell isKindOfClass:[UITableViewCell class]])
{
cell = cell.superview;
}
// Make the cell selected
[(UITableViewCell *)cell setSelected:YES animated:YES];
}
I'd recommend the first solution, as Andrey Chevozerov said in the comments of one of the answers:
It's better to not use superview for such tasks. Especially in cascade.
Upvotes: 0
Reputation: 1029
Why you're using tags for textfields? The proper way is:
UITextField
;indexPath.row
to the corresponding cell's text field;in textFieldShouldBeginEditing
place a code for selecting cell:
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:textfield.tag inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
Upvotes: -2
Reputation: 20021
textfield.superview.superview
gives you the cell instance.
Use the delegate to get the action
Upvotes: 1