Swift 4 UITableView 将一个单元格设为 UITextView

Posted

技术标签:

【中文标题】Swift 4 UITableView 将一个单元格设为 UITextView【英文标题】:Swift 4 UITableView make one cell as UITextView 【发布时间】:2018-04-08 18:02:00 【问题描述】:

我有一个动态的Table 作为UITableView 并且所有单元格都正常(从我的array 检索) 但是我只需要一个单元格作为 TextView 就可以输入文本。在文本更改上,我需要检索文本用户输入。 这个怎么做?

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return array.count+1 //to allow this input field
    

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    if(indexPath.row < array.cont)
       //normal cell from array
        let cell =  Table.dequeueReusableCell(withIdentifier: "myCell")
        cell?.textLabel?.text = array[indexPath.row]
        cell?.isUserInteractionEnabled = true;
        cell?.textLabel?.adjustsFontSizeToFitWidth = true
        cell?.textLabel?.textAlignment = .center;
        return cell!;
    else
      //create input text field (DON'T KNOW HOW)
    


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
      if(indexPath.row < array.cont)
              //.. perform action ..
       else
         //retrieve input text (DONT know How)
       
 

【问题讨论】:

【参考方案1】:

UITableViewCell 中创建UITextView 非常简单:

let textView: UITextView = UITextView(frame: CGRect(x: 0, y: 20, width: 311.00, height: 50.00))  // Set frames as per requirements
textView.textAlignment = NSTextAlignment.justified
cell.contentView.addSubView(textView) 

但这会在滚动表格时导致不正确的值。最好的方法是创建一个自定义单元格并在那里添加UITextView。这是自定义单元格。保持约束不变。

在使用自定义单元格之前,您需要在表格中注册它。所以:

let nib = UINib(nibName: "TextCell", bundle: nil)
Table.register(nib, forCellReuseIdentifier: "TextCell")  

不要忘记将单元格的标识符放在 xib 中。

现在在 cellForRowAtIndexPath 中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    if(indexPath.row < array.cont)
       //normal cell from array
        let cell =  Table.dequeueReusableCell(withIdentifier: "myCell")
        cell?.textLabel?.text = array[indexPath.row]
        cell?.isUserInteractionEnabled = true;
        cell?.textLabel?.adjustsFontSizeToFitWidth = true
        cell?.textLabel?.textAlignment = .center;
        return cell!;
    else
      //create input text field (DON'T KNOW HOW)
      let cell = tableView.dequeueReusableCell(withIdentifier: "TextCell", for: indexPath) as! TextCell
      // Access UITextView by cell.textView
      return cell
    

主要问题是 - 根据UITextView 高度的动态单元格大小。但这完全取决于您的要求。您可以关注this 的帖子。

【讨论】:

这不是最好的方法,因为该单元格可能会被重复使用,并且您将在不正确的单元格上显示文本视图或在单元格上显示多个文本视图。最好创建一个内置文本视图的自定义单元格,然后将这种自定义单元格从队列中取出以获取适当的索引路径。 @maddy:好点。但是我将其远离范围,因为 OP 知道这一点(他已经在处理单元子视图)。但我理解你的担心。将更新我的答案。 不,OP 不适用于单元格子视图。到目前为止只有一个标准的UITableViewCell。你的回答只会导致更多的问题和问题。 更新了我的答案【参考方案2】:

您可以使用委托模式或 NSNotification 来实现这一点。 这是使用委托模式的解决方案。

    使用 xib 创建新的 UITableViewCell 并在单元格的 contentView 上添加 textView,设置重用标识符,然后在 ViewController 中注册 xib

    tableView.register(UINib(nibName: "xib 文件名", bundle: nil), forCellReuseIdentifier: "Identifier here")

    现在在类之外的任何地方定义协议 // 你可以给任何名字 // 这里我们确认类以避免任何保留循环

    协议 CustomCellDelegate :class 函数返回文本(文本:字符串)

    现在在我们在上面创建 xib 时创建的同一类 UITableViewCell 中初始化“var delegate : CustomCellDelegate?”。 并确认协议 UITextViewDelegate 然后在单元格类中写这个

    覆盖 func awakeFromNib() super.awakeFromNib() textView.delegate = 自我

然后将这些函数添加到tableViewCell的同一个类中

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool 
        if(text == "\n") 
            textView.resignFirstResponder()
            return false
        
        return true


func textViewDidEndEditing(_ textView: UITextView) 
        delegate.returnText(text : textView.text ?? "")

    现在在 ViewController 类中

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
                if indexPath.row == array.count  // this will call the cell with TextView at the end , you can play with any indexPath to call the cell
    
                 let cell = tableView.de... // Deque the cell with TextView here using reuse identifier
                 cell.delegate = self
                 return cell
                
               else 
                 // deque other cells
              
    
    

我们将编写 ViewController 的扩展并确认我们的自定义协议

extension ViewController : CustomCellDelegate 

// this function will get called when you end editing on textView
 func returnText(text :String) 
  print(text) // you may save this string in any variable in ViewController class 
  


【讨论】:

【参考方案3】:

在自定义单元格中添加一个 TextView,将其隐藏,在需要时显示

【讨论】:

为什么要隐藏它并显示它?使用两种不同类型的细胞。这是正确的解决方案。【参考方案4】:

如果您想让 textView 位于所有单元格的顶部,请将 UIView 拖放到单元格之前的 tableView 中。

此视图将随单元格一起滚动。

根据需要在其中插入一个 textView 来设计此视图,并使用 textView 的委托方法来执行操作。

【讨论】:

以上是关于Swift 4 UITableView 将一个单元格设为 UITextView的主要内容,如果未能解决你的问题,请参考以下文章

Swift:将包含自定义标签的单元格添加到 UITableView

比较一个结构的两个值并在 UITableView swift 4.0 中获取额外的单元格

SWIFT:UITableView 将所有单元格的数据(文本字段和标签)传递给 UIViewController

Swift:UITableView 单元格受到另一部分中单元格的影响

(Swift)如何通过重新加载 UITableView 根据 UITextfield 输入(动画)显示/隐藏单元格?

Swift - uitableview 重用单元格时用户输入混淆?