【问题标题】:iOS How to select row, when a person selects the UITextField inside it?iOS如何选择行,当一个人选择里面的UITextField?
【发布时间】:2013-07-08 09:26:30
【问题描述】:

所以我有一个UITableView,其中所有单元格中都有一个UITextField 作为带有tag=1 的子视图。令我困扰的是,当用户单击 textField 并对其进行编辑以了解发生在哪一行时,我想要。我认为可以解决的方法是在选择子视图(UITextField)时使单元格自行选择。我怎样才能做到这一点?

我尝试使用数组,但由于单元格被重复使用,所以它不起作用。循环遍历所有行太慢了。

【问题讨论】:

  • 尝试使用 Uitextfield 委托方法..?

标签: ios objective-c uitableview uitextfield


【解决方案1】:

默认禁用每个单元格中的UITextField 并使用UITableView 委托方法didSelectRowAtIndexPath:

  1. 将所选行的 indexPath 存储在属性中
  2. 启用UITextField
  3. UITextField 成为第一响应者

在你的类扩展中定义属性:

@interface MyTableViewController ()
@property (strong, nonatomic) NSIndexPath *activeIndex;
@end

在您的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];
}

UITextField 退出其第一响应者状态时,您需要再次禁用它。

假设您的UITableViewController 是每个UITextField 的代表,您可以在UITextFieldDelegate 方法的实现中执行此操作:

-(void)textFieldDidEndEditing:(UITextField *)textField 
{
    [textField setEnabled:NO];
}

【讨论】:

    【解决方案2】:

    textfield.superview.superview 为您提供单元格实例。 使用委托获取操作

    【讨论】:

    • 此类任务最好不要使用superview。尤其是级联。仅仅因为您需要对 superview 的类进行一些检查,并且有一些更简单的方法来完成这项工作。
    • @AndreyChevozerov:为什么?为什么需要一些检查?为什么不能使用superview?
    • 我同意@AndreyChevozerov 在级联中使用superview 的观点,并且您的回答特别危险,因为没有保证UITextField 在单元格中只会下降两层(一个可以嵌入它在多个子视图中)。
    • 谢谢,它是这样工作的,但只有一个超级视图。我能够像这样在 textFieldShouldReturn 方法中获得 indexPath: NSIndexPath index = [self.tableView indexPathForCell:(UITableViewCell)textField.superview];
    • 嵌入的人是编写代码的人,我认为。所以他很容易管理。是的,是他正确实施它。我给它两次超级视图,因为通常它有单元格内的内容视图
    【解决方案3】:

    正确的做法是把textFields的bounds转换成相对于tableView,然后用这个rec​​t的原点得到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];
    

    【讨论】:

      【解决方案4】:

      使用UITextFieldDelegate 了解用户何时开始编辑UITextField(使用textFieldDidBeginEditing:)。

      那么两种解决方案:

      解决方案 1:子类化您的单元格并使其成为 UITextField 的代表。

      然后在您的自定义单元格的textFieldDidBeginEditing: 中,选中该单元格:

      // MyCustomCell.m
      - (void)textFieldDidBeginEditing:(UITextField *)textField
      {
          [self setSelected:YES animated:YES];
      }
      

      解决方案 2:将视图控制器设为 UITextField 委托,然后从那里选择正确的单元格。

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

      我推荐第一个解决方案,正如 Andrey Chevozerov 在其中一个答案的 cmets 中所说:

      最好不要将 superview 用于此类任务。尤其是级联。

      【讨论】:

      • 第二种解决方案?是的,这就是我引用你的原因;)。我不会担心这里的表现很艰难,我不认为这太糟糕了(我认为只是按照指示并在此处进行isa 比较)。
      【解决方案5】:

      下面的代码将返回 NSIndexPath。这可以写成 UITextField delegate -

      [tableView indexPathForRowAtPoint:textField.superview.superview.frame.origin];
      

      试试上面的代码。

      【讨论】:

      • 使用坐标检索单元格。哇。这是非常不安全的imo。并不能保证textfield.superview.superview 将返回该单元格。文本字段可以嵌入到多个子视图中。
      【解决方案6】:

      为什么要为文本字段使用标签? 正确的做法是:

      1. 为单元格创建自定义类;
      2. 为您的UITextField 做一个出口;
      3. 创建单元格时,将您的视图控制器指定为单元格文本字段的代表;
      4. 将标签 == indexPath.row 分配给相应单元格的文本字段;
      5. textFieldShouldBeginEditing中放置一个选择单元格的代码:

        [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:textfield.tag inSection:0] 动画:YES scrollPosition:UITableViewScrollPositionNone];

      【讨论】:

      • ...Apple 确实记录了这两种方法。他们同样正确。对于非常小的项目,标签可以节省您的时间。当然,它们也很脆弱,因此对于许多人来说,自定义单元格是最好的选择(尤其是在这里,您可以使用文本字段委托)。但同样,使用标签并不是不正确
      • 如果 tableview 上有 2 个或更多 seciton 怎么办?
      • 当您有多个部分时,您可以在标签中编码部分编号。这不是什么大问题。
      • 是的,Apple 记录了这两种方法。但我不确定它们是否相等。我的经验告诉我,一些记录在案的方法并不像看起来那么好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      相关资源
      最近更新 更多