Summary
Hello Apple Developers,
I've made a custom UITableViewCell that includes a UITextField and UILabel. When I run the simulation the UITableViewCells pop up with the UILabel and the UITextField, but the UITextField isn't clickable so the user can't enter information. Please help me figure out the problem.
Thank You!
Sampson
What I want:
What I have:
Screenshot Details:
As you can see when I tap on the cell the UITextField isn't selected. I even added placeholder text to the UITextField to see if I am selecting the UITextField and the keyboard just isn't popping up, but still nothing.
Relevant Code:
UHTextField
import UIKit
class UHTextField: UITextField {
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
convenience init(placeholder: String) {
self.init(frame: .zero)
self.placeholder = placeholder
}
private func configure() {
translatesAutoresizingMaskIntoConstraints = false
borderStyle = .none
textColor = .label
tintColor = .blue
textAlignment = .left
font = UIFont.preferredFont(forTextStyle: .body)
adjustsFontSizeToFitWidth = true
minimumFontSize = 12
backgroundColor = .tertiarySystemBackground
autocorrectionType = .no
}
}
UHTableTextFieldCell
import UIKit
class UHTableTextFieldCell: UITableViewCell, UITextFieldDelegate {
static let reuseID = "TextFieldCell"
let titleLabel = UHTitleLabel(textAlignment: .center, fontSize: 16, textColor: .label)
let tableTextField = UHTextField()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func set(title: String) {
titleLabel.text = title
tableTextField.placeholder = "Enter " + title
}
private func configure() {
addSubviews(titleLabel, tableTextField)
let padding: CGFloat = 12
NSLayoutConstraint.activate([
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding),
titleLabel.heightAnchor.constraint(equalToConstant: 20),
titleLabel.widthAnchor.constraint(equalToConstant: 80),
tableTextField.centerYAnchor.constraint(equalTo: centerYAnchor),
tableTextField.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 24),
tableTextField.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding),
tableTextField.heightAnchor.constraint(equalToConstant: 20)
])
}
}
LoginViewController
class LoginViewController: UIViewController, UITextFieldDelegate {
let tableView = UITableView()
let loginTableTitle = ["Username", "Password"]
override func viewDidLoad() {
super.viewDidLoad()
configureTableView()
updateUI()
createDismissKeyboardTapGesture()
}
func createDismissKeyboardTapGesture() {
// create the tap gesture recognizer
let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing))
// add it to the view (Could also add this to an image or anything)
view.addGestureRecognizer(tap)
}
func configureTableView() {
view.addSubview(tableView)
tableView.layer.borderWidth = 1
tableView.layer.borderColor = UIColor.systemBackground.cgColor
tableView.layer.cornerRadius = 10
tableView.clipsToBounds = true
tableView.rowHeight = 44
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.removeExcessCells()
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: loginTitleLabel.bottomAnchor, constant: padding),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
tableView.heightAnchor.constraint(equalToConstant: 88)
])
tableView.register(UHTableTextFieldCell.self, forCellReuseIdentifier: UHTableTextFieldCell.reuseID)
}
func updateUI() {
DispatchQueue.main.async {
self.tableView.reloadData()
self.view.bringSubviewToFront(self.tableView)
}
}
}
extension LoginViewController: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: UHTableTextFieldCell.reuseID, for: indexPath) as! UHTableTextFieldCell
let titles = loginTableTitle[indexPath.row]
cell.set(title: titles)
cell.titleLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
cell.tableTextField.delegate = self
return cell
}
}
Again thank you all so much for your help. If you need more clarification on this let me know.
I figured out the solution. Thank you so much Claude31 your solution put me on the right path.
LoginViewController
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: UHTableTextFieldCell.reuseID, for: indexPath) as! UHTableTextFieldCell
let titles = loginTableTitle[indexPath.row]
cell.set(title: titles)
cell.titleLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
cell.contentView.isUserInteractionEnabled = false // <----
return cell
}
UHTableTextFieldCell
The selection still worked without this next section, but I think I should still include it.
private func configure() {
addSubviews(titleLabel, tableTextField)
self.isUserInteractionEnabled = true // <----
tableTextField.delegate = self // <----
let padding: CGFloat = 12
NSLayoutConstraint.activate([
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding),
titleLabel.heightAnchor.constraint(equalToConstant: 20),
titleLabel.widthAnchor.constraint(equalToConstant: 80),
tableTextField.centerYAnchor.constraint(equalTo: centerYAnchor),
tableTextField.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 24),
tableTextField.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding),
tableTextField.heightAnchor.constraint(equalToConstant: 20)
])
}