【问题标题】:didEndEditingRowAt not called with custom tableview celldidEndEditingRowAt 未使用自定义表格视图单元格调用
【发布时间】:2018-09-11 12:56:12
【问题描述】:

我有一个表格视图 (SettingsViewController),用作显示用户信息(姓名、电子邮件、电话号码等)的用户信息视图。这类似于标准的 iOS 联系页面。

每个单元格都有一个跨单元格大小拉伸的文本字段,因此一旦处于“编辑”模式,用户就可以更新他/她的信息。

我还有一个自定义单元格(SettingsCell),我在其中使用文本字段等设置单元格。

SettingsViewController(排除了很多tabelview设置代码):

class SettingsViewController: UITableViewController{

    let cellId = "cellId"

    var apiController: APIController?

    var firstName: String?
    var lastName: String?
    var email: String?
    var phoneNumber: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .mainWhite()
        tableView = UITableView(frame: CGRect.zero, style: .grouped)
        tableView.register(SettingsCell.self, forCellReuseIdentifier: cellId)

        setupNavigation()

    }

    fileprivate func setupNavigation() {
        editButtonItem.action = #selector(showEditing)
        editButtonItem.title = "Edit"
        editButtonItem.tintColor = .mainWhite()
        self.navigationItem.rightBarButtonItem = editButtonItem
    }


    @objc func showEditing(sender: UIBarButtonItem)
    {
        if(self.tableView.isEditing == false)
        {
            self.tableView.isEditing = true
            self.navigationItem.rightBarButtonItem?.title = "Save"
            self.tableView.reloadData()
        }
        else
        {
            self.tableView.isEditing = false
            self.navigationItem.rightBarButtonItem?.title = "Edit"
            self.tableView.reloadData()
        }
    }

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

        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! SettingsCell

        if self.tableView.isEditing == true {
            cell.textField.isEnabled = true

            if indexPath.section == 2 {
                cell.textField.keyboardType = .phonePad
            }
        } else {
            cell.textField.isEnabled = false
        }

        cell.selectionStyle = .none

        filloutUserInfo(indexPath: indexPath, cell: cell)

        return cell
    }

    override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
        return false
    }

    //THIS NEVER GETTING EXECUTED
    override func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {
        print("editing done for row \(indexPath?.item)")
    }

    override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
        return .none
    }

}

设置单元格:

class SettingsCell: UITableViewCell, UITextFieldDelegate {

    let textField: UITextField = {
        let tf = UITextField()
        tf.isEnabled = false
        return tf
    }()

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

    override func layoutSubviews() {
        super.layoutSubviews()
        addSubview(textField)
        textField.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)

        textField.addDoneButtonOnKeyboard()
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我现在遇到的问题是,在我进入编辑模式并更改给定单元格的文本后,表格视图实际上并不能识别这一点。 didEndEditingRowAt 永远不会被调用,并且永远不会显示该打印语句。我怀疑这与文本字段没有以任何方式连接到 tableviewcontroller 有关,但我不知道如何解决这个问题。

我需要能够知道用户何时完成编辑,以便在格式不正确和禁用保存按钮时显示警报。

【问题讨论】:

    标签: ios swift uitableview


    【解决方案1】:

    您需要实现一个回调来侦听从SettingsCell 到您的ViewControllertextField endEditing 事件。

    为了实现这一点,这里是更新的SettingsCell

    class SettingsCell: UITableViewCell, UITextFieldDelegate {
    
        let textField: UITextField = {
            let tf = UITextField()
            tf.isEnabled = false
            tf.addDoneButtonOnKeyboard()
            return tf
        }()
    
        public var onEndEditing: ((String?) -> Void)?
    
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            textField.removeFromSuperview()
            addSubview(textField)
            textField.delegate = self
    
            textField.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0)
        }
    
        func textFieldDidEndEditing(_ textField: UITextField) {
            self.onEndEditing?(textField.text)
        }
    
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            textField.resignFirstResponder()
            return true
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    

    现在更新 cellForRowAt 以监听 endEditing 事件,如下所示,

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! SettingsCell
    
        if self.tableView.isEditing == true {
            cell.textField.isEnabled = true
            cell.onEndEditing = { text in 
                print("Cell Editing finished with text: \(text)")
             }
            if indexPath.section == 2 {
                cell.textField.keyboardType = .phonePad
            }
        } else {
            cell.textField.isEnabled = false
        }
    
        cell.selectionStyle = .none
    
        filloutUserInfo(indexPath: indexPath, cell: cell)
    
        return cell
    }
    

    【讨论】:

    • 非常感谢。唯一的问题是,当仅添加/删除一个字符时,它实际上“结束”了。所以当用户结束输入时实际上并没有改变。
    • 认为您只需要从 aout 子视图中删除 textField.removeFromSuperview() 并添加到 textFieldDidEndEditing 方法的末尾
    • 尝试删除 textfield.resignFirstResponder()
    • 不,如果我删除 textfield.resignFirstResponder() 操作是一样的。
    • 我修复它的方法是执行以下操作:将 resignFirstResponder() 和 removeFromSuperview() 移到我们调用 cell.onEndEditing 的部分内的 SettingsViewController 类。这可确保在用户在文本字段之间切换时更新所有值。 if let text = text { self.setNewUserInfo(indexpath: indexPath, info: text) cell.textField.resignFirstResponder() cell.textField.removeFromSuperview() }
    猜你喜欢
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多