ios - 动态添加自定义 UITableViewCell

标签 ios swift uitableview

我想创建一个列表(UITableView),其中包含一个包含三个标签的自定义 View (UITableViewCell),用于获取用户数据,比如说名字和姓氏,部门,当您单击添加按钮(列表外)时,一个新用户自定义 View 被添加到列表中,您可以在其中输入其他用户详细信息。 我知道如何在 tableView 中创建 customView 如果它只是一个文本,我知道如何附加到 tableView,但我想附加到 tableview 的是单击按钮时的 customView。

为了向 tableView 添加文本,我做了类似下面的操作。

datas.insert("new data", at: 0)
        jobTableView.beginUpdates()
        jobTableView.insertRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
        jobTableView.endUpdates()

我如何为 customView 做这件事?

下面是我的表格

UITableviewClass

public class MiddlePartCell: BaseCell, UITableViewDelegate, UITableViewDataSource {

let tableCell = "tableCell"

lazy var jobTableView: UITableView = {
   let tv = UITableView()
    tv.backgroundColor = .brown
    tv.dataSource = self
    tv.delegate = self
    return tv
}()

lazy var addMoreButton: UIButton = {
    let button = UIButton(type: .system)
    button.setBackgroundImage(UIImage(named: "plus"), for: .normal)
    button.tintColor = .black
    button.addTarget(self, action: #selector(handleAddJob), for: .touchUpInside)
    button.layer.cornerRadius = 20
    return button
}()

@objc private func handleAddJob(){
    //what should i do here 
    //i need to insert the custom view to the top index
    jobTableView.beginUpdates()
    jobTableView.insertRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
    jobTableView.endUpdates()
}

override func setupView() {
    super.setupView()
    backgroundColor = .green
    addSubview(jobTableView)
    addSubview(addMoreButton)

    jobTableView.register(UITableViewCell.self, forCellReuseIdentifier: tableCell)

    _ = addMoreButton.anchor(nil, left: leftAnchor, bottom: bottomAnchor, right: nil, topConstant: 0, leftConstant: 10, bottomConstant: 10, rightConstant: 0, widthConstant: 50, heightConstant: 50)

    _ = jobTableView.anchor(topAnchor, left: leftAnchor, bottom: addMoreButton.topAnchor, right: rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: frame.width, heightConstant: frame.height)
}

public func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: tableCell, for: indexPath)

    cell.textLabel?.text = datas[indexPath.item]

    return cell
}

public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return datas.count
  }
}

最佳答案

首先,您必须将 UITableViewCell 子类化为带有 UITextField 的 UITableViewCell。当然,您可以在 cellForRowAt 委托(delegate)函数中添加 UITextField,但我更喜欢使用自定义 UITableViewCell。

class UITableViewCellWithTextField: UITableViewCell {

    var textField: UITextField!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setup()
    }

    func setup() {

        let textField = UITextField(frame: self.contentView.frame)
        self.contentView.addSubview(self.textField)
    }
}

接下来,您必须将此自定义 UITableViewCell 注册到您的 UITableView 中。将此添加到您现有的 UITableViewCell 注册代码行。

jobTableView.register(UITableViewCell.self, forCellReuseIdentifier: tableCell)
jobTableView.register(UITableViewCellWithTextField.self, forCellReuseIdentifier: "TextFieldCell")

下一步是声明一个变量来表示用户已经发起了添加新工作的功能。

public class MiddlePartCell: BaseCell, UITableViewDelegate, UITableViewDataSource {

    var isHandlingAddJob = false

    ...
}

然后在你的 handleAddJob 函数中

func handleAddJob(){

    self.isHandlingAddJob = true
    datas.insert("new data", at: 0)
    jobTableView.beginUpdates()
    jobTableView.insertRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
    jobTableView.endUpdates()
}

最后是让 UITableView 知道传入的新单元格要处理新作业的添加,并且应该使用自定义文本字段单元格。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if indexPath.row == 0 && self.isHandlingAddJob {

        // Handling new job cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldCell", for: indexPath) as! UITableViewCellWithTextField
        return cell
    }

    let cell = tableView.dequeueReusableCell(withIdentifier: tableCell, for: indexPath)

    cell.textLabel?.text = datas[indexPath.item]
    return cell
}

附言希望我能正确理解您的问题,哈哈。

要在自定义表格 View 单元格中保留文本字段的数据,您必须使用委托(delegate)模式。首先,您必须使自定义表格 View 单元格或 MiddlePartCell 类符合 UITextFieldDelegate。我会选择后者。

class MiddlePartCell: BaseCell, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {

    ...
}

然后在您的 cellForRowAt 函数中,您将自定义单元格的文本字段委托(delegate)设置为您的 MiddlePartCell。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if indexPath.row == 0 && self.isHandlingAddJob {

        // Handling new job cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldCell", for: indexPath) as! UITableViewCellWithTextField
        cell.returnKeyType = .Done
        cell.textField.delegate = self
        return cell
    }

    ...
}

最后,使用 UITextFieldDelegate 函数。当在键盘上单击完成时,您的单元格将重新加载为没有 UITextField 的普通 UITableViewCell。

func textFieldShouldReturn(textField: UITextField) -> Bool {

    self.isHandlingAddJob = false
    self.datas.first! = textField.text!
    self.jobTableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 0, inSection: 0)], withRowAnimation: .Automatic)
    return true
}

关于ios - 动态添加自定义 UITableViewCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41176172/

相关文章:

ios - Swift/XCode 与 Kingfisher - 无法从 Web 加载图像

ios - NSFetchedresultsController 部分 Name KeyPath 基于当前位置和其他位置之间的范围

ios - 如何在 View Controller 上获取导航栏?

macos - 如何在 Swift 的 AppDelegate 中使用自己的 ViewController 打开一个新窗口

ios - Swift - 位置提示不会很快发生

ios - '-[UITableViewController loadView] 加载了 "OG7-5c-Gm7-view-xGh-Gb-9hr"nib 但没有获得 UITableView。

ios - 将获取数据与 UITableView 不同部分的核心数据分开

ios - 为什么 range.length 值在 shouldChangeCharactersInRange 委托(delegate)方法中因退格而改变?

ios - 是否有可能读取 iOS 设备存储信息

swift - 不能用 Swift 中的存储属性覆盖