如何在自定义单元格中同步选择文本视图的事件?

Posted

技术标签:

【中文标题】如何在自定义单元格中同步选择文本视图的事件?【英文标题】:How to synchronise events on the selection of a textview in a custom cell? 【发布时间】:2019-06-05 18:45:36 【问题描述】:

我在自定义单元格中有一个 textView,当我开始编辑时,我希望按钮出现在单元格中。为此,我创建了一个变量“selectedIndexPathRow”,在“textViewDidBeginEditing”函数中将 textView 的 indexPath.row 分配给该变量。

func textViewDidBeginEditing(_ textView: UITextView) 

let touchPosition:CGPoint = textView.convert(CGPoint.zero, to: self.createStoryTableView)

let indexPath = self.createStoryTableView.indexPathForRow(at: touchPosition)

self.selectedIndexPathRow = indexPath?.row ?? 0

.....

之后,在我的 cellForRowAt 中,我可以根据 indexPathRow 是否与变量匹配来显示或隐藏按钮。如下:

if indexPath.row == selectedIndexPathRow 

cell.inputTextView.isEditable = true
cell.createBtnStack.isHidden = false

     else 
        cell.createBtnStack.isHidden = true
    

问题是按钮仅在编辑完成后出现(在按 enter 或单击 textView 外部时),而不是在编辑开始时(或单击 textView 时)。

为了解决这个问题,我尝试了以下方法:

将 tableview.reloaddata() 放入“didBeginEditing”。这会同步生成按钮,但会导致 textview 冻结。

使用'textViewShouldBeginEditing'函数如下尝试预先设置selectIndexPathRow变量:

func textViewShouldBeginEditing(_ textView: UITextView) -> 布尔

让 touchPosition:CGPoint = textView.convert(CGPoint.zero, 到: self.createStoryTableView)

让 indexPath = self.createStoryTableView.indexPathForRow(at: touchPosition)

self.selectedIndexPathRow = indexPath?.row ?? 0

返回真

但是这样做的结果并不一致-有时可以在单击后直接编辑文本视图而没有显示任何按钮,有时会显示按钮但您必须再次单击才能编辑文本视图。

如果您对如何解决此问题有任何建议,请告诉我。

【问题讨论】:

【参考方案1】:

通过将单元格设置为其文本字段的委托,让单元格管理自己的编辑状态。这是一个示例游乐场:

import UIKit
import PlaygroundSupport

class Cell: UITableViewCell 
    let textView = UITextView()
    let button = UIButton()
    lazy var stackView: UIStackView = 
        let stack = UIStackView(arrangedSubviews: [textView, button])
        stack.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(stack)
        NSLayoutConstraint.activate([
            stack.heightAnchor.constraint(equalToConstant: 120),
            stack.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 12),
            stack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -12),
            stack.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 12),
            stack.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -12)
            ])
        button.setTitle("Button", for: .normal)
        button.addTarget(self, action: #selector(tapButton), for: .touchUpInside)
        textView.delegate = self
        return stack
    ()

    func configure() 
        contentView.backgroundColor = .gray
        _ = stackView
        button.isHidden = !textView.isFirstResponder
    

    @objc private func tapButton() 
        contentView.endEditing(true)
    


extension Cell: UITextViewDelegate 
    func textViewDidBeginEditing(_ textView: UITextView) 
        button.isHidden = false
    
    func textViewDidEndEditing(_ textView: UITextView) 
        button.isHidden = true
    


class V: UITableViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        tableView.register(Cell.self, forCellReuseIdentifier: String(describing: Cell.self))
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return 1
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: Cell.self), for: indexPath)
        (cell as? Cell)?.configure()
        return cell
    



PlaygroundPage.current.liveView = V()

【讨论】:

感谢乔希的回复。将单元格设置为 textView 的委托是一个好主意。唯一的问题是我仍然需要访问 tableView 才能在 textViewDidBeginEditing 中执行其他事件,例如就像滚动到 selectedRow 一样。除非我弄错了,否则我无法从单元格访问 tableView。 通过沿着响应者链向上走,很容易从它的任何孩子那里获得任何父 UIResponder(包括一个 tableview)。请在此处查看我的答案:***.com/questions/55578880/…

以上是关于如何在自定义单元格中同步选择文本视图的事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何停止在自定义表格视图单元格中交换数据?

自定义表格视图单元格中的 UITextField。点击单元格/文本字段时显示选择器视图

如何在自定义单元格中点击以编程方式添加的 UiImageViews 推送新视图

如何在自定义滑动(而不是滑动删除)单元格(滑动到邮件/短信)中点击一个单元格时删除在其他 TableView 单元格中添加的子视图

以swift语言在自定义表格视图单元格中更新进度视图下载

如何固定表格视图中自定义单元格文本字段的标签值?