【发布时间】:2021-04-26 07:21:14
【问题描述】:
好的,所以我有一个带有 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()
}
}
问题是,当键盘出现将其设置为第一响应者而不是原始文本字段时,我不知道如何在 InputAccessoryView 中引用文本字段(图像中的“150”)。强>
我希望通过键盘输入来更改 InputAccessoryView 内 TextField 中的文本。现在原来的 textField 仍然是第一响应者。
我尝试在函数 (cellForRowAt) 内创建时将 inputTextField 设置为 becomeFirstResponder,但这显然为时过早,因为键盘还没有出现。
我研究了类似的问题/答案,但没有一个涉及如何在 InputAccessoryView 中引用 textField ——尤其是来自 tableViewCell 时。
【问题讨论】:
-
您是否尝试过延迟异步调用
becomeFirstResponder?试试:DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { textField.becomeFirstResponder() } -
这实际上是让 inputAccessoryView 文本字段响应的最佳方式,谢谢!
标签: ios swift uitextfield tableview inputaccessoryview