如何将InputAccessoryView中的TextField设置为第一响应者[Swift]

ubof19bj  于 2022-12-17  发布在  Swift
关注(0)|答案(2)|浏览(129)

好的,我有一个带有textField的tableView,当用户点击tableView中的textField时,键盘会显示一个自定义的InputAccessoryView,如下所示:

下面是创建自定义InputAccessoryView的代码,我已经在cellForRowAt和textFieldDidBeginEditing(如下所示)中为tableView(每行执行不同的功能)尝试过了。

func textFieldDidBeginEditing(_ textField: UITextField) {
        print("textFieldDidBeginEditing")
        if textField.tag == 1 {
            profileDataTextField.addToolbarInputAccessoryView()
        }
}

我将它创建为UITextField的扩展:

extension UITextField {

func addToolbarInputAccessoryView() {
    let screenWidth = UIScreen.main.bounds.width
    // Create Main Container View
    let mainContainerView = UIView()
    mainContainerView.backgroundColor = .clear
    mainContainerView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: 120)
    
    // Create Heading Label
    let label = UILabel()
    label.textColor = .white
    label.font = UIFont(name: "BrandonGrotesque-Bold", size: 20)
    label.text = "Enter New Weight"
    label.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true
    label.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
    label.textAlignment = .center
    
    // Create Input Container View
    let inputContainerView = UIView()
    inputContainerView.backgroundColor = .white
    inputContainerView.heightAnchor.constraint(equalToConstant: 80.0).isActive = true
    inputContainerView.widthAnchor.constraint(equalToConstant: screenWidth).isActive = true
    
    // Create inputTextField
    let inputTextField = UITextField()
    inputTextField.translatesAutoresizingMaskIntoConstraints = false
    inputTextField.placeholder = "150"
    inputTextField.textAlignment = .left
    inputTextField.textColor = .darkGray
    inputTextField.font = UIFont(name: "BrandonGrotesque-Bold", size: 50)
    inputTextField.backgroundColor = .white
    inputTextField.layer.cornerRadius = 4
    inputTextField.layer.masksToBounds = true
    inputTextField.borderStyle = .none
    
    // Create metricTextField
    let metricLabel = UILabel()
    metricLabel.textColor = .darkGray
    metricLabel.font = UIFont(name: "BrandonGrotesque-Bold", size: 18)
    metricLabel.text = "lbs"
    metricLabel.textAlignment = .left
    
    // Create Done button
    let doneButton = UIButton()
    doneButton.backgroundColor = .systemIndigo
    doneButton.setTitle("Done", for: .normal)
    doneButton.titleLabel?.font = UIFont(name: "BrandonGrotesque-Bold", size: 20)
    doneButton.cornerRadius = 4
    doneButton.translatesAutoresizingMaskIntoConstraints = false
    doneButton.addTarget(self, action: #selector(doneTapped), for: .touchUpInside)
    
    // Create cancel button
    let cancelButton = UIButton()
    cancelButton.backgroundColor = .systemRed
    cancelButton.setTitle("Cancel", for: .normal)
    cancelButton.titleLabel?.font = UIFont(name: "BrandonGrotesque-Bold", size: 20)
    cancelButton.cornerRadius = 4
    cancelButton.translatesAutoresizingMaskIntoConstraints = false
    cancelButton.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
    
    // Main Stack View
    let mainStackView = UIStackView()
    mainStackView.axis = .vertical
    mainStackView.distribution = .fill
    mainStackView.alignment = .fill
    mainStackView.spacing = 10.0
    mainStackView.backgroundColor = .clear
    
    // Toolbar StackView
    let toolbarStackView = UIStackView()
    toolbarStackView.axis = .horizontal
    toolbarStackView.distribution = .fillEqually
    toolbarStackView.alignment = .fill
    toolbarStackView.spacing = 20.0
    toolbarStackView.backgroundColor = .white
    
    // Input Stackview
    let inputStackView = UIStackView()
    inputStackView.axis = .horizontal
    inputStackView.distribution = .equalCentering
    inputStackView.alignment = .center
    inputStackView.spacing = 5.0
    inputStackView.backgroundColor = .white
    
    // Put it all together
    mainStackView.addArrangedSubview(label)
    
    inputStackView.addArrangedSubview(inputTextField)
    inputStackView.addArrangedSubview(metricLabel)
    
    toolbarStackView.addArrangedSubview(cancelButton)
    toolbarStackView.addArrangedSubview(inputStackView)
    toolbarStackView.addArrangedSubview(doneButton)
    toolbarStackView.translatesAutoresizingMaskIntoConstraints = false
    
    inputContainerView.addSubview(toolbarStackView)
    
    mainStackView.addArrangedSubview(inputContainerView)
    mainStackView.translatesAutoresizingMaskIntoConstraints = false
    
    toolbarStackView.leadingAnchor.constraint(equalTo: inputContainerView.leadingAnchor, constant: 15).isActive = true
    toolbarStackView.trailingAnchor.constraint(equalTo: inputContainerView.trailingAnchor, constant: -15).isActive = true
    toolbarStackView.topAnchor.constraint(equalTo: inputContainerView.topAnchor, constant: 15).isActive = true
    toolbarStackView.bottomAnchor.constraint(equalTo: inputContainerView.bottomAnchor, constant: -15).isActive = true
    
    mainContainerView.addSubview(mainStackView)
    
    inputAccessoryView = mainContainerView
}

@objc func cancelTapped() {
    self.resignFirstResponder()
}

@objc func doneTapped() {
    self.resignFirstResponder()
}

}

问题是,当键盘显示将textField(而不是原始textField)设置为第一响应者时,我不知道如何在InputAccessoryView中引用textField(图中为“150”)。

我希望从键盘输入更改输入附件视图内的文本字段中的文本。现在原始的文本字段仍然是第一响应者。
我尝试过在函数(cellForRowAt)中创建inputTextField时将其设置为FirstResponder,但这显然为时过早,因为键盘还没有出现。
我研究过类似的问题/答案,但是没有一个涉及如何在InputAccessoryView中引用textField--特别是当来自tableViewCell时。

7uhlpewt

7uhlpewt1#

尝试异步调用becomeFirstResponder,并延迟一段时间以允许键盘初始化:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { 
    textField.becomeFirstResponder()
}
um6iljoc

um6iljoc2#

**首先,**我支持将其作为自定义视图,而不是扩展,以便轻松访问textField
其次要访问它,请按当前方式向文本字段添加一个标记,如下所示

inputTextField.tag = 33

最后像这样访问textField

profileDataTextField.addToolbarInputAccessoryView()
guard let field = profileDataTextField.inputAccessoryView.viewWithTag(33) else { return }
field.becomeFirstResponder()

相关问题