如何在uitextfield委托方法中获取单元格索引路径?

时间:2012-09-07 13:27:33

标签: iphone objective-c uitableview user-interface uitextfield

我在自定义单元格中有两个文本字段如何在textfield委托方法中获取Tableview单元格的索引路径值我想从用户获取输入值并将其保存到relavent对象。用户可以通过单击单元格中的按钮(添加更多)来添加更多单元格。

enter image description here

提前致谢...

11 个答案:

答案 0 :(得分:18)

更新到iOS7!

现在,iOS7中的新功能代码应为:

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];

答案 1 :(得分:13)

更动态的解决方案(没有硬编码的超级视图级别和不同iOS版本的相同代码)。

此外,如果单元格不可见,indexPathForCell:将无效,因此我使用indexPathForRowAtPoint:作为解决方法。

//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];

答案 2 :(得分:10)

这就是我一直在做的事情并且运气好了。我抓住textField框架的原点。将其转换为一个点。然后将该点转换为索引路径。

-(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];

}

答案 3 :(得分:4)

尝试使用此方法从tableview控制器

中动态获取文本字段
 #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;
}

答案 4 :(得分:2)

要获取indexPath,请尝试以下代码。

    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];

告诉你,你完成了。

简单来说,

NSIndexPath *indexPath = [self.tableview indexPathForCell:(UITableViewCell *)[(UIVIew *)[textfield superview] superview]];

if(IS_IOS7_OR_GREATER) {
    cell = (UITableViewCell *)[[[textfield superview] superview] superview];
}

检查更新的答案。

答案 5 :(得分:1)

将单元格索引路径值设置为UITextField tag属性,您可以在委托方法中访问索引路径,例如textfield.tag

答案 6 :(得分:1)

您可以在cellForRowAtIndexPath中设置文本字段的标记:这样它可以存储单元格和文本字段的信息

例如:如果是第4行中的单元格,则第1和第2文本字段的标记可以分别为41和42。同样,对于第5行,文本字段的标签应为51和52,依此类推......

然后在textfield委托方法中,您可以获取textfield.tag来识别活动文本字段。

答案 7 :(得分:1)

我找到这个答案,搜索如何在UITextField中找到单元格的索引路径。

所以,多亏了上面的答案,我把我的代码放在这里,希望可能有用。

- (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];
    }
}

这样,当提示键盘通知时:

- (void)keyboardDidShow:(NSNotification*)notification {
    [self searchSelectedIndexPath:self.tableView];
}

答案 8 :(得分:0)

这可以在任何实例的Objective-C运行时中完成(不必是UITextField),任何关联的对象(不必是NSIndexPath)。

对于这个问题,我们可以创建一个类别UIView+RepresentingIndexPath

我们的界面允许我们设置和检索NSIndexPath:

@interface UIView (RepresentingIndexPath)
- (void)representIndexPath:(NSIndexPath *)indexPath;
- (NSIndexPath *)representedIndexPath;
@end

我们的实现使用Objective-C关联对象在视图上设置和检索索引路径:

#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

行动中:

- (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);
}

最后一点说明!如果你能够在不这样做的情况下实现你想要做的事情,那么应该真正避免在运行时中乱搞。我以为我会添加另一个解决方案!

答案 9 :(得分:0)

如果像我这样的人需要@Kerkness的答案(这个对我来说真的很有用),请快速:

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)
}

它应该是直截了当的:你明白了,然后你得到了indexPath,并用它做你需要的任何事情!

答案 10 :(得分:0)

感谢@Luka,它的工作方式很棒。 这是快速的4解决方案,

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()
        })
    }
}