【问题标题】:UITextField inside UITableViewCell: becomeFirstResponder in didSelectRowAtIndexPathUITableViewCell 中的 UITextField:didSelectRowAtIndexPath 中的 becomeFirstResponder
【发布时间】:2013-03-26 09:26:21
【问题描述】:

我目前正在尝试使其正常工作。任何帮助表示赞赏。

我有一个自定义的UITableViewCell,里面有一个UITextField。当我选择表格单元格时,我想让UITextField 第一个响应者。
但是 [textField becomeFirstResponder]; 返回 false

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
  UITextField *textField;
  for (UIView *view in [cell subviews]) {
    if ([view isMemberOfClass:[UITextField class]]) {
      textField = ((UITextField *)view);
    }
  }

  [textField becomeFirstResponder];
}

根据要求,初始化文本字段。这是在UITableViewCell 子类中完成的:

- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

  if (self) {
    // Init Textfield
    _textField = [[UITextField alloc] init];
    _textField.backgroundColor = [UIColor clearColor];
    _textField.delegate = self;
    [self addSubview:_textField];
  }

return self;
}

【问题讨论】:

  • 你的 textField==nil; ?我的意思是你能得到文本字段参考吗?
  • 是的,我得到了 textField 参考。方法 becomeFirstResponder 只返回 false,因为由于某种原因无法将 textField 提升为 firstResponder。
  • 请告诉我们您如何创建UITextFields。也许您的文本字段委托方法之一返回 NO?

标签: ios objective-c uitableview uitextfield


【解决方案1】:

如果您有自定义单元格,则可以执行以下操作:

@implementation CustomCell

#pragma mark - UIResponder

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (BOOL)becomeFirstResponder
{
    return [self.textField becomeFirstResponder];
}

@end

然后在table view delegate里面:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if ([cell canBecomeFirstResponder]) {
        [cell becomeFirstResponder];
    }
}

【讨论】:

  • 嘿@josh-fuggle 谢谢你。问题是一岁。所以我真的不记得我是如何解决它的。但这应该可行!
  • 是的,我明白了。我只是想展示另一种解决问题的方法。我喜欢这种设计,因为您可以有几个不同的子视图,每个子视图以不同的方式响应 UIResponder,同时在表视图委托中保持相同的干净代码。
  • 我遇到了同样的问题,但这并没有为我解决。 becomeFirstResponder 总是返回 NO。还有什么我可以尝试的吗?
【解决方案2】:

为每个UITextField 提供tag 并使用以下代码:

UITableViewCell* cell = (UITableViewCell*)sender.superview.superview;
UITextField *txtField = (UITextField*)[cell viewWithTag:tag];
[txtField becomeFirstResponder];

didSelectRowAtIndexPath 方法中。

它的工作非常好.. :)

【讨论】:

  • 我使用我使用的方法得到了 txtField,但我尝试了你的方法,遗憾的是它也不起作用。 viewWithTag 与我所做的有何不同?谢谢。
  • 我对你的 Que 感到困惑。你在 tblViewCell 上添加 textField 。那么它是如何调用 didSelectRowAtIndexPath 的?通过break pint检查它是否运行??
  • 添加这个方法 - (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder];返回是; }
  • textFieldShouldReturn 方法和 becomeFirstResponder 有什么关系?
  • 这不回答任何问题。不要浪费你的时间,人们。
【解决方案3】:

我相信你需要设置你textFielddelegate属性。

在调用[textField becomeFirstResponder]之前,将textField.delegate = self;添加到您的方法中

【讨论】:

  • 文本字段是 UITableView 单元格的一部分,它是 UITextField 的代表。但是,我也尝试在单元类中调用 becomeFirstResponder ,但这也不起作用。
  • @SebastianBorggrewe 这不是好的做法。 UITableViewCell 是视图,而不是控制器。您应该将委托设置为您的 TableViewController 并确保它符合 UITextFieldDelegate 协议
  • 感谢您的提示。但它仍然不能解释 becomefirstresponder 行为,不是吗?
  • @SebastianBorggrewe 我认为应该......我没有我的mac,所以我现在无法进行实验。如果到我回家的时候还没有解决这个问题,我会测试。
【解决方案4】:

我认为您应该在创建单元格时在文本字段中包含一个标记值:

- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
      self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

      if (self) {
        // Init Textfield
        _textField = [[UITextField alloc] init];
        _textField.backgroundColor = [UIColor clearColor];
        _textField.delegate = self;
        _textField.tag = 999;
        [self addSubview:_textField];
      }

    return self;
}

并在 didSelectRowAtIndexPath 方法上使用标签值来恢复对象:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
  UITextField *textField = (UITextField*)[cell viewWithTag:999];


  if (![textField isFirstResponder]){
     [textField becomeFirstResponder];
  }

}

我已经包含一个验证来控制文本字段是否已经是第一响应者。

希望它能如你所愿

【讨论】:

    【解决方案5】:
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
      UITextField *textField;
      for (id subV in [cell subviews]) {
        if ([subV isKindOfClass:[UITextField class]]) {
          textField = (UITextField *)subV;
          [textField becomeFirstResponder];
          break;
        }
      }
    
    
    }
    

    我认为这对你会有帮助。

    【讨论】:

      【解决方案6】:

      更新了@josh-fuggle 的答案以使用 Swift 2.2。

      import Foundation
      import UIKit
      
      class CustomTableCell:UITableViewCell {
      
          @IBOutlet var textValue: UITextField!
      
          override func canBecomeFirstResponder() -> Bool {
              return true
          }
      
          override func becomeFirstResponder() -> Bool {
              return self.textValue.becomeFirstResponder()
          }
      }
      

      这是在您的表视图委托中:

      func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
      
              let cell = tableView.cellForRowAtIndexPath(indexPath)
              if ((cell?.canBecomeFirstResponder()) != nil) {
                  cell?.becomeFirstResponder()
              }
      }
      

      【讨论】:

      • 此外,您可能会发现覆盖 isFirstResponder 也很有用,以返回您的文本输入字段是否是第一响应者。
      【解决方案7】:

      你可以这样做:

      class CustomCell: UITableViewCell {
          @IBOutlet weak var textField: UITextField!
      
          override func awakeFromNib() {
              super.awakeFromNib()
              let tapGesture = UITapGestureRecognizer(target: self, action: #selector(contentViewTapped))
              self.contentView.addGestureRecognizer(tapGesture)
          }
          @objc func contentViewTapped() {
              _ = self.textField.becomeFirstResponder()
          }
      }
      

      【讨论】:

        【解决方案8】:

        [self.titleLab performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.2];

        【讨论】:

        • 延迟它是肮脏的,只会导致副作用,你可能不想有。
        猜你喜欢
        • 2018-08-31
        • 2019-05-30
        • 1970-01-01
        • 1970-01-01
        • 2015-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多