didEndEditingRow未使用自定义tableview单元调用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了didEndEditingRow未使用自定义tableview单元调用相关的知识,希望对你有一定的参考价值。

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

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

我也有一个自定义单元格(SettingsCell),这是我用文本字段等设置单元格的地方。

设置视图控制器(排除很多tableview设置代码):

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")
    

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

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

答案

你需要实现一个回调来监听从textField到你的SettingsCellViewController 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

以上是关于didEndEditingRow未使用自定义tableview单元调用的主要内容,如果未能解决你的问题,请参考以下文章

自定义对话框的默认按钮输入焦点传递

TabLayout +ViewPager 自定义Tab的UI

v-card 中的 bootstrap-vue v-tabs 呈现“未定义”

Vue可自定义tab组件

element的标签页(tabs)组件样式自定义

vue项目中tab切换和自定义组件的使用