在iOS 8中,becomeFirstResponder无法正常工作。

20

我正在使用UITextField的becomeFirstResponder方法来显示键盘。这在iOS 7中有效。但是在iOS 8中,该方法不能显示键盘。

 UITextField *txtAddNew = [[UITextField alloc] initWithFrame:CGRectMake(10,10,240, 21)];
 txtAddNew.font = [UIFont fontWithName:@"Helvetica" size:16];
 txtAddNew.clearButtonMode = UITextFieldViewModeWhileEditing;
 txtAddNew.returnKeyType = UIReturnKeyDone;
 txtAddNew.delegate = self;
 txtAddNew.autocorrectionType = UITextAutocorrectionTypeNo;
 txtAddNew.tag = 15;

 // Open keyboard
 [txtAddNew becomeFirstResponder];

有没有办法在iOS 8中实现这个?


1
我没有看到你将那个文本框作为子视图添加到任何一个视图中。 - Kris Gellci
8个回答

49

试着像下面这样调用 becomeFirstResponder

[txtAddNew performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0];

根据苹果公司的说法,

只有当当前响应者可以放弃第一响应者状态(canResignFirstResponder)并且新的响应者可以成为第一响应者时,响应对象才会成为第一响应者。

您可以调用此方法使响应对象(如视图)成为第一响应者。但是,仅在该视图属于视图层次结构时才应调用它。如果视图的window属性持有UIWindow对象,则已将其安装在视图层次结构中;如果返回nil,则该视图已与任何层次结构分离。


这是很奇怪的,当 [txtAddNew becomeFirstResponder] 在某些情况下没有起作用时。那这到底有什么区别呢? - mskw
@mskw 可能是因为调用选择器强制执行了 resignFirstResponder - Pedro Paulo Amorim

18

Swift 3

以下是被接受的答案的Swift 3版本。为了使其工作,我还需要添加延迟。

txtAddNew.perform(
    #selector(becomeFirstResponder), 
    with: nil, 
    afterDelay: 0.1
)

3

我认为你错过了将txtAddNew添加到Mainviewaddsubview步骤。

   txtAddNew.tag = 15;
   [self.view addsubview:txtAddNew];  

   // Open keyboard
  [txtAddNew becomeFirstResponder];

1
在你的代码中添加这行。希望它能起作用。
[txtAddNew performSelectorOnMainThread:@selector(becomeFirstResponder) withObject:nil afterDelay:0.0];

1

Swift 4和iOS 11

在我的情况下,无论我尝试了什么,都无法设置第一个响应者,直到我尝试了这个。

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.isKind(of: YOURTABLEVIEWCELL.self) {
        if let yourCell = cell as? YOURTABLEVIEWCELL{
            yourCell.yourUiTextField.becomeFirstResponder()
        }
    }
}

希望这能帮助到遇到同样问题的人。

0
有时候,首先辞去第一响应者会有所帮助:
var tapGesture = UITapGestureRecognizer()
tapGesture.rac_gestureSignal().subscribeNext { [weak self] (_) -> Void in
    self?.inputTextField.resignFirstResponder()
    self?.inputTextField.becomeFirstResponder()
}

self.charViewsContainer.addGestureRecognizer(tapGesture)

这对我有用,你有任何苹果文档可以证明这个吗? - Austin

0

对于iOS 9.3,以下方法适用于我:

 private var searchTextFieldShouldReturn = false

    override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)

            self.searchTextFieldShouldReturn = false
            self.searchTextField.becomeFirstResponder()
        }
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)

        self.searchTextFieldShouldReturn = true
        self.searchTextField.resignFirstResponder()
    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {
            self.searchTextFieldShouldReturn = true
            textField.resignFirstResponder()

            return true
        }

    func textFieldShouldEndEditing(textField: UITextField) -> Bool {

            return self.searchTextFieldShouldReturn
        }

所以您需要确保还实现了textFieldShouldEndEditing协议。


0

以防其他人和我遇到相同的问题:

我将IBOutlet连接到了我的UITextField上。错误地在我的viewDidLoad方法中初始化了它。也就是说,[[textField alloc] init];。我删除了这个并且一切都正常工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接