在swift中的`becomeFirstResponder()`中发出问题

时间:2018-03-22 12:43:38

标签: ios swift keyboard uitextfield uitextfielddelegate

我有六个textfields。现在,如果我的所有textfield都已填满并点按任何textfield,则应始终关注第六个textfield&显示键盘。我尝试了下面的代码,但它没有显示keyboard,只有在点击第六个textfield时才会显示焦点。请告诉我这个问题是什么?

func textFieldDidBeginEditing(_ textField: UITextField) {
     textField.inputAccessoryView = emptyView
        if let textOneLength = textFieldOne.text?.length ,let textTwoLength = textFieldTwo.text?.length ,let textThreeLength = textFieldThree.text?.length , let textFourLength = textFieldFour.text?.length,let textFiveLength = textFieldFive.text?.length , let textSixLength = textFieldSix.text?.length {
            if (textOneLength > 0) && (textTwoLength > 0) && (textThreeLength > 0) && (textFourLength > 0) && (textFiveLength > 0) && (textSixLength > 0) {
                self.textFieldSix.becomeFirstResponder()
            } else if (textOneLength <= 0) && (textTwoLength <= 0) && (textThreeLength <= 0) && (textFourLength <= 0) && (textFiveLength <= 0) && (textSixLength <= 0){
                self.textFieldOne.becomeFirstResponder()
            }
        }
}

8 个答案:

答案 0 :(得分:3)

我认为接受的答案是黑客。我们可以做的其他事情是在touchDown上检测UITextField,检查最后一个textField是否应该在焦点上并对其进行becomeFirstResponder()。接下来,如果最后一个应该成为焦点,我们应该禁止关注其他textFields。我们可以在textFieldShouldBeginEditing方法中执行此操作。

此处ViewController的示例。只需连接3个textFields,所有文件都应按预期工作(Swift 4):

class ViewController: UIViewController {

    @IBOutlet weak var firstTextField: UITextField!
    @IBOutlet weak var secondTextField: UITextField!
    @IBOutlet weak var thirdTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        firstTextField.delegate = self
        secondTextField.delegate = self
        thirdTextField.delegate = self

        firstTextField.addTarget(self, action: #selector(textFieldTouch(_:)), for: .touchDown)
        secondTextField.addTarget(self, action: #selector(textFieldTouch(_:)), for: .touchDown)
        thirdTextField.addTarget(self, action: #selector(textFieldTouch(_:)), for: .touchDown)
    }

    @IBAction private func textFieldTouch(_ sender: UITextField) {
        if shouldFocusOnLastTextField {
            thirdTextField.becomeFirstResponder()
        }
    }

    private var shouldFocusOnLastTextField: Bool {
        return firstTextField.text?.isEmpty == false && secondTextField.text?.isEmpty == false  && thirdTextField.text?.isEmpty == false
    }

}

extension ViewController: UITextFieldDelegate {

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        guard shouldFocusOnLastTextField else { return true }
        return textField == thirdTextField
    }

}

其他更简单的方法来检查将要聚焦的textField:

extension ViewController: UITextFieldDelegate {

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        guard firstTextField.text?.isEmpty == false &&
            secondTextField.text?.isEmpty == false  &&
            thirdTextField.text?.isEmpty == false &&
            textField != thirdTextField else { return true }

        thirdTextField.becomeFirstResponder()
        return false
    }

}

答案 1 :(得分:1)

您的实施问题在于,您尝试在第一个响应者已分配给另一个textField时进行分配。
以下代码应该可以解决问题:

$index = $this->client->initIndex('index');

$index->doSomeAlgoliaFunction();

答案 2 :(得分:0)

它应该是有效的。您确定模拟器具有显示keywoard启用的属性吗? 您可以使用以下键更改该属性:Command + Shift + k

答案 3 :(得分:0)

我知道这对我来说也很奇怪,但是延迟对文本字段的关注对我有用。

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                self.textFieldOne.becomeFirstResponder()
            }

我在textFieldDidBeginEdting&amp;中添加了上面的代码。它就像魔法一样。

答案 4 :(得分:0)

在这种情况下,您希望在发生之前拒绝尝试的编辑;当我们希望拒绝尝试编辑时,我们还需要将第六个文本字段设置为新的第一响应者。

extension MyViewController: UITextFieldDelegate {
  func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    if textFieldOne.text?.isEmpty == false && textFieldTwo.text?.isEmpty == false  && textFieldThree.text?.isEmpty == false && textFieldFour.text?.isEmpty == false && textFieldFive.text?.isEmpty == false && textFieldSix.text?.isEmpty == false  {
      if textField != textFieldSix {
        textFieldSix.becomeFirstResponder()
        return false
      } else {
        return true
      }
    } else {
      return true
    }
  }
}

答案 5 :(得分:0)

1 在viewcontroller中设置UITextfielddelegate

2 将自我委托设置为每个文本字段

3 为每个文字字段添加标记值

4 添加textfield.becomeFirstResponder()

5 检查使用标记的条件是否指定文本字段值

答案 6 :(得分:0)

参考此答案https://stackoverflow.com/a/27098244/4990506

  

如果当前,响应者对象只成为第一个响应者   响应者可以辞退第一响应者状态(canResignFirstResponder)   并且新的响应者可以成为第一响应者。

     

您可以调用此方法来创建响应者对象,例如查看第一响应者。但是,您应该只在该视图上调用它   它是视图层次结构的一部分。如果视图的窗口属性包含   UIWindow对象,它已安装在视图层次结构中;如果它   返回nil,视图与任何层次结构分离。

首先将委托设置为所有字段

self.textFieldOne.delegate = self
self.textFieldTwo.delegate = self
self.textFieldThree.delegate = self
self.textFieldFour.delegate = self
self.textFieldFive.delegate = self
self.textFieldSix.delegate = self

然后委托

extension ViewController : UITextFieldDelegate{
    func textFieldDidBeginEditing(_ textField: UITextField) {
        if self.textFieldOne.hasText ,self.textFieldTwo.hasText ,self.textFieldThree.hasText ,self.textFieldFour.hasText ,self.textFieldFive.hasText ,self.textFieldSix.hasText  {
            textFieldSix.perform(
                #selector(becomeFirstResponder),
                with: nil,
                afterDelay: 0.1
            )
        }else if !self.textFieldOne.hasText ,!self.textFieldTwo.hasText ,!self.textFieldThree.hasText ,!self.textFieldFour.hasText ,!self.textFieldFive.hasText ,!self.textFieldSix.hasText {
            textFieldOne.perform(
                #selector(becomeFirstResponder),
                with: nil,
                afterDelay: 0.1
            )
        }
    }
}

答案 7 :(得分:-1)

要检查任何文本字段,请使用此代码

for view in self.view.subviews {
    if let textField = view as? UITextField {
        print(textField.text!)
    }
}

**您还可以使用此标识来识别文本 -

if let txtFieldINeed = self.view.viewWithTag(99) as? UITextField {
    print(txtFieldINeed.text!)
}

**然后使用 -     txtFieldINeed.becomeFirstResponder()

**确保打开此选项 -     * iOS模拟器 - &gt;硬件 - &gt;键盘      *取消选中&#34;连接硬件键盘&#34;