如何将 UITextView 嵌入 UITableViewCell 与作为委托的自定义单元格?
Posted
技术标签:
【中文标题】如何将 UITextView 嵌入 UITableViewCell 与作为委托的自定义单元格?【英文标题】:How to embed UITextView inside UITableViewCell with custom cell that's the delegate? 【发布时间】:2019-02-21 10:44:45 【问题描述】:我有一个带有两个自定义单元格的 UITableViewController - 一个包含一个 UITextField(供用户输入标题),另一个包含一个 UITextView(供用户输入描述)。每当这些变化时,我想更新我的内存对象(这是一个具有两个变量的结构 - memoryTitle 和 memoryDescription)。
memoryTitle 看起来很简单 - 在我的 ViewController 上我有以下内容:
@IBAction func memoryTitleChanged(_ sender: UITextField)
memory.memoryTitle = sender.text ?? ""
UITextView 让我有些困惑。我遇到了两个问题 - 我无法以与 UITextField 相同的方式创建操作,所以我的下一个想法是让 ViewController 成为委托并使用 textViewDidChange 更新 memory.memoryDescription 但这让我想到了我的第二个问题。
为了使 UITextView 单元格动态调整大小,我使用了以下完美运行的教程 (https://medium.com/@georgetsifrikas/embedding-uitextview-inside-uitableviewcell-9a28794daf01) 来制作我的自定义单元格:
class DetailTextTableViewCell: UITableViewCell, UITextViewDelegate
//Found below method for resizing UITextView and cell - https://medium.com/@georgetsifrikas/embedding-uitextview-inside-uitableviewcell-9a28794daf01
@IBOutlet weak var memoryDescriptionTextView: UITextView!
var textChanged: ((String) -> Void)?
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
memoryDescriptionTextView.delegate = self
memoryDescriptionTextView.backgroundColor = UIColor.red
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
//Found below method for resizing UITextView and cell - https://medium.com/@georgetsifrikas/embedding-uitextview-inside-uitableviewcell-9a28794daf01
func textChanged(action: @escaping (String) -> Void)
self.textChanged = action
func textViewDidChange(_ textView: UITextView)
textChanged?(textView.text)
现在我坚持使用 DetailTextTableViewCell 作为 UITextView 的委托,所以我不确定如何在文本更改时更新 ViewController 中的内存对象。如果有人有任何想法或指导,将不胜感激!
提前谢谢你。
【问题讨论】:
从代码看来,您有一个闭包textChanged
,它将在文本更改时被调用。所以我相信你会在 cellForRow 方法上给它赋值,比如cell.textChanged
。使用此闭包将值设置为 memory.memoryDescription
【参考方案1】:
首先,你不需要textChanged
方法
func textChanged(action: @escaping (String) -> Void)
然后,您需要在控制器的 cellForRowAt
中为每个特定单元格分配您的 textChanged
闭包变量(顺便说一句,这是一个好方法)。
在闭包内部声明,当文本视图发生变化时,某些项目的(来自表格视图数据源数组)属性将被分配String
闭包参数,如果需要,然后为此IndexPath
重新加载某些单元格@
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
...
cell.textChanged = text in
self.dataSourceArray[indexPath.row].stringProperty = text
// tableView.reloadRows(at: [indexPath], with: .none)
// if you want to reload row, move calling closure
// to `textViewDidEndEditing` instead
...
【讨论】:
嗨,@RobertDresler 是否需要重新加载单元格?因为用户已经输入了 UItextview 并且已经可以显示输入的文本,那么为什么需要重新加载单元格? @AtulParmar 哦,好吧,没必要。【参考方案2】:在您的单元格上方声明此协议DetailTextTableViewCell
protocol CellDelegate
func textViewChanged(textView : UITextView)
在您的 DetailTextTableViewCell
中添加一个委托变量
var delegate : CellDelegate?
在 tableView 行的单元格中,将 self 分配给单元格的委托属性
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
...
cell.delegate = self
在您的DetailTextTableViewCell
中添加这一行 textViewDidChange
func textViewDidChange(_ textView: UITextView)
textChanged?(textView.text)
delegate?.textViewChanged(textView)
现在在你的视图控制器中实现委托功能
func textViewChanged(textView: UITextView)
【讨论】:
请不要这样做。如果他已经有闭包变量,为什么要为此创建委托协议?【参考方案3】:在cellForRowAt
里面做
let cell = ///
cell.memoryDescriptionTextView.tag = indexPath.row
cell.memoryDescriptionTextView.delegate = self
并在 vc 中实现委托方法
【讨论】:
【参考方案4】:尝试在cellForRowAt
方法中启用文本视图的用户交互属性。
cell.memoryDescriptionTextView.delegate = self
cell.memoryDescriptionTextView.isUserInteractionEnabled = true
【讨论】:
以上是关于如何将 UITextView 嵌入 UITableViewCell 与作为委托的自定义单元格?的主要内容,如果未能解决你的问题,请参考以下文章
如何将菜单选项添加到 NSTextAttachment 弹出菜单是 UITextView?
以编程方式在 UITableViewCell 下添加 UITextView 和 UIImageView Swift 4
如何将文本包装在 Iphone 的 UITable 单元格中?
可编辑的 UITextView 可以嵌入到 UIPopoverController 中吗?