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
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.
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];
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];
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.
Thanks, @Luka, it works in a great way. Here is the swift 4 solution,
var selectedIndexPath: IndexPath?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShowHide(_ :)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShowHide(_ :)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func searchSelectedIndexPath(view: UIView) {
view.subviews.forEach { (subview) in
if view is UITextView, view.isFirstResponder == true {
var cell:UIView? = view;
while cell != nil && !(cell is UITableViewCell) {
cell = cell?.superview;
}
if cell != nil {
self.selectedIndexPath = self.dashBoardTableView.indexPathForRow(at: (cell?.center)!)
return
}
}
self.searchSelectedIndexPath(view: subview)
}
}
// Keyboard notification observer menthod
@objc fileprivate func keyboardWillShowHide(_ notification: NSNotification){
if notification.name == NSNotification.Name.UIKeyboardWillShow {
UIView.animate(withDuration: duration, animations: { () -> Void in
self.selectedIndexPath = nil;
self.searchSelectedIndexPath(view: self.tableView)
if let indexpath = self.selectedIndexPath {
self.tableView.scrollToRow(at: indexpath, at: .top, animated: false)
} else{
self.bottomContriant.constant = keyboardHeight
self.view.layoutSubviews()
}
})
} else {
self.bottomContriant.constant = 15
UIView.animate(withDuration: duration, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
}
set cell indexpath value to UITextField
tag
property and you can access the indexpath in delegate methods like textfield.tag