Reputation: 437
I have two textfields in a custom cell how to get the indexpath value of Tableview cell in textfield delegate methods I want to get the input value from user and save it to the relavent object. the user can add more cells by clicking button(Add More) in cell..
Thanks in Advance...
Upvotes: 14
Views: 14220
Reputation: 2323
In case somebody like me needs @Kerkness' answer (this one really worked for me) in swift:
func textFieldDidBeginEditing(_ textField: UITextField) {
let origin: CGPoint = textField.frame.origin
let point: CGPoint? = textField.superview?.convert(origin, to: tableView)
let indexPath: IndexPath? = tableView.indexPathForRow(at: point ?? CGPoint.zero)
tableView.scrollToRow(at: indexPath!, at: .middle, animated: true)
}
It should be straight forward enough: you get the point then you get the indexPath and do whatever you need with it!
Upvotes: 2
Reputation: 21520
I find this answer searching how can I find the index path of a cell with inside a UITextField.
So, thanks to the answer above, I put my code here, hoping might be usefull.
- (void)searchSelectedIndexPath:(UIView*)view {
// This allow to find selected index path for a table view cell with a text field inside.
for (UIView* subview in view.subviews) {
if ([view isKindOfClass:[UITextField class]]) {
if ([view isFirstResponder]) {
UIView *cell = view;
while (cell && ![cell isKindOfClass:[UITableViewCell class]]) {
cell = cell.superview;
}
self.selectedIndexPath = [self.tableView indexPathForRowAtPoint:cell.center];
return;
}
}
[self searchSelectedIndexPath:subview];
}
}
In this way, when keyboard notification will be raise:
- (void)keyboardDidShow:(NSNotification*)notification {
[self searchSelectedIndexPath:self.tableView];
}
Upvotes: 1
Reputation: 11217
Try this method to get textfield dynamically anywhere from your tableview
controller
#pragma mark - Get textfield indexpath
- (NSIndexPath *)TextFieldIndexpath:(UITextField *)textField
{
CGPoint point = [textField.superview convertPoint:textField.frame.origin toView:self.TblView];
NSIndexPath * indexPath = [self.TblView indexPathForRowAtPoint:point];
NSLog(@"Indexpath = %@", indexPath);
return indexPath;
}
Upvotes: 4
Reputation: 18855
This can be done in the Objective-C runtime for any instance (doesn't have to be UITextField), with any associated object (doesn't have to be NSIndexPath).
For this question, we could create a category UIView+RepresentingIndexPath
.
Our interface allows us to set and retrieve an NSIndexPath:
@interface UIView (RepresentingIndexPath)
- (void)representIndexPath:(NSIndexPath *)indexPath;
- (NSIndexPath *)representedIndexPath;
@end
Our implementation uses Objective-C associated objects to set and retrieve an index path on a view:
#import "UIView+RepresentingIndexPath.h"
#import <objc/runtime.h>
static char IndexPathKey;
@implementation UIView (RepresentingIndexPath)
- (void)representIndexPath:(NSIndexPath *)indexPath
{
objc_setAssociatedObject(self, &IndexPathKey, indexPath, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSIndexPath *)representedIndexPath
{
return objc_getAssociatedObject(self, &IndexPathKey);
}
@end
In action:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TextFieldTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TextFieldCell" forIndexPath:indexPath];
[cell.textField addTarget:self action:@selector(textFieldTextChanged:) forControlEvents:UIControlEventEditingChanged];
[cell.textField representIndexPath:indexPath];
return cell;
}
- (void)textFieldTextChanged:(UITextField *)sender
{
NSIndexPath *indexPath = [sender representedIndexPath];
NSLog(@"%@", indexPath);
}
💣
One final note! Messing around in the runtime should really be avoided if you can achieve what you're trying to do without doing so. Just thought I'd add another solution!
Upvotes: 1
Reputation: 359
This is how I have been doing it and have been having better luck. I grab the origin of the textField frame. Convert that to a point. Then convert the point to an index path.
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
CGPoint origin = textField.frame.origin;
CGPoint point = [textField.superview convertPoint:origin toView:self.tableView];
NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint:point];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
Upvotes: 10
Reputation: 21137
A more dynamic solution (no hardcoded superview levels and same code for different iOS versions).
Further, indexPathForCell:
will not work if the cell is not visible, therefore I use indexPathForRowAtPoint:
as workaround.
//find the UITableViewcell superview
UIView *cell = textField;
while (cell && ![cell isKindOfClass:[UITableViewCell class]])
cell = cell.superview;
//use the UITableViewcell superview to get the NSIndexPath
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:cell.center];
Upvotes: 13
Reputation: 252
You can set the tags of textfields in cellForRowAtIndexPath: such that it stores info of both cell and text field
For example : If it is cell in 4th row, tag of 1st and 2nd textfields can be 41 and 42 respectively. Similarly, tags of textfields should be 51 and 52 for 5th row and so on...
Then in textfield delegate method, you can get textfield.tag to identify active textfield.
Upvotes: 1
Reputation: 21426
Update to iOS7!
With new features in iOS7 now code should be :
UITableViewCell *textFieldRowCell;
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// Load resources for iOS 6.1 or earlier
textFieldRowCell = (UITableViewCell *) textField.superview.superview;
} else {
// Load resources for iOS 7 or later
textFieldRowCell = (UITableViewCell *) textField.superview.superview.superview;
// TextField -> UITableVieCellContentView -> (in iOS 7!)ScrollView -> Whoola!
}
NSIndexPath *indexPath = [self.tableView indexPathForCell:textFieldRowCell];
Upvotes: 19
Reputation: 1897
To get The indexPath try the following code.
UIView *contentView = (UIVIew *)[textfield superview];
UITableViewCell *cell = (UITableViewCell *)[contentView superview];
if(IS_IOS7_OR_GREATER) {
cell = (UITableViewCell *)[[contentView superview] superview];
}
NSIndexPath *indexPath = [self.tableview indexPathForCell:cell];
Tats it you are done.
To be simple,
NSIndexPath *indexPath = [self.tableview indexPathForCell:(UITableViewCell *)[(UIVIew *)[textfield superview] superview]];
if(IS_IOS7_OR_GREATER) {
cell = (UITableViewCell *)[[[textfield superview] superview] superview];
}
Check the updated answer.
Upvotes: 2
Reputation: 1920
set cell indexpath value to UITextField
tag
property and you can access the indexpath in delegate methods like textfield.tag
Upvotes: 1