【问题标题】:UITextField won't becomeFirstResponderUITextField 不会成为FirstResponder
【发布时间】:2013-06-08 19:29:10
【问题描述】:

我在让文本字段接受 becomeFirstResponder 指令时遇到问题。

我提供了一种自定义机制来在导航栏中创建标题。我有另一个成功使用相同技术的视图控制器。在 viewDidAppear 我开火了:

- (void)addTitleTextField
{
    CGRect textFrame = self.parentViewController.navigationController.navigationBar.frame;
    textFrame.size.width = 300.0;
    textFrame.origin.y = (768.0 - 300.0)/2;
    textFrame.size.height = 30.0;
    textFrame.origin.x = 7.0;
    self.titleTextField = [[UITextField alloc] initWithFrame:textFrame];
    self.titleTextField.placeholder = NSLocalizedString(@"New Multiple Choice Quiz", @"New Multiple Choice Quiz");
    self.titleTextField.borderStyle = UITextBorderStyleRoundedRect;
    self.titleTextField.font = [UIFont boldSystemFontOfSize:20.0];
    self.titleTextField.textAlignment = NSTextAlignmentCenter;
    self.titleTextField.backgroundColor = [UIColor whiteColor];
    self.titleTextField.textColor = [UIColor blackColor];
    self.titleTextField.delegate = self;
    [self.titleTextField setAutocorrectionType:UITextAutocorrectionTypeNo];
    self.titleTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
    [self.titleTextField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
    self.activeTextField = self.titleTextField;
    self.parentViewController.navigationItem.titleView = self.titleTextField;
    [self.titleTextField becomeFirstResponder];
}

self.titleTextField 将允许我设置文本值,但如果您使用 canBecomeFirstResponder 检查它会返回 NO。如您所见,我在 parentViewController 上进行了设置。我尝试使用委托来尝试让 parentViewController 设置它。当我执行委托并检查 textField canBecomeFirstResponder 是否返回 YES 时,我仍然无法使其接受 firstResponder 订单。有任何想法吗?文档说“只有当前响应者可以放弃第一响应者状态(canResignFirstResponder)并且新响应者可以成为第一响应者时,响应者对象才会成为第一响应者”。

【问题讨论】:

  • 触摸字段时是否弹出键盘?
  • 您是否已将<UITextFieldDelegate> 添加到您的类定义中?你设置textfield.delegate = self;了吗?
  • 您还应该将文本字段添加到您的视图中,使用addSubView:
  • @sangony 是的,键盘弹出。
  • @philosopherdog 如果它解决了您的问题,请接受答案!

标签: ios objective-c cocoa-touch


【解决方案1】:

你是在告诉 UITextField 成为后台线程上的选择器吗?

[textField performSelectorOnMainThread:@selector(becomeFirstResponder) withObject:nil 
  waitUntilDone:YES];

基本原理:在主线程以外的方法上调用 UIKit 方法(即更新视图)将不起作用。 .这可能正在发生。 (不清楚从哪里调用 addTitleTextField 方法)。

是否还有需要一些时间辞职的第一响应者?

[textField performSelectorOnMainThread:@selector(becomeFirstResponder) withObject:nil afterDelay:0.0];

基本原理:如果另一个字段挂在第一响应者身上(或正在辞职的过程中),它将给它时间清理辞职,等待下一个运行循环。 . . . .通常下一个运行循环将有足够的时间让前一个响应者清理,或者您可以尝试像 0.05 这样的短延迟。

【讨论】:

  • 太棒了!为什么这会完全有效?我认为这与其他胎面无关。
  • 为什么不执行SelectorOnMainThread?如果问题是代码在后台线程上运行,我认为您会想要这样做...
  • @JasperBlues 感谢充实回复。就我而言,我认为这不是线程问题。第一响应者可能还没有辞职。
【解决方案2】:

您可能需要将 textField 添加到视图层次结构:

v.addSubview(textField)

【讨论】:

  • 如果不在视图层次结构中,他将如何看到 TextView?
  • textField.superview != nil 表示 textField 在视图层次结构中。
【解决方案3】:

要做的另一件事是确保 textField 已启用(检查 Interface Builder,然后您可以通过代码执行任何禁用操作)。

我花了将近一个小时试图找出问题所在:我通过子类化 UITextField 并将canBecomeFirstResponder 覆盖为始终return true 得到了解决方法。这迫使它最终显示键盘并编辑文本字段,但我注意到我无法点击/选择/复制/粘贴文本字段。用户交互已启用,然后我终于看到未选中已启用...我责怪 Apple 在禁用一段 UI 时没有显示任何视觉提示(就像使用 Hidden 一样)lol

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    相关资源
    最近更新 更多