【问题标题】:Dynamically resizing an IOS tableview cells which have a textview embedded in swift动态调整 IOS tableview 单元格的大小,其中嵌入了 swift 的 textview
【发布时间】:2018-04-12 12:20:51
【问题描述】:

我已经尝试了以下代码,它给出了正确的 textview 框架高度

func textViewDidChange(_ textView: UITextView) {

    myToDoList[keyArray[sect]]![row] = textView.text
    var frame = textView.frame
    frame.size.height = textView.contentSize.height
    textView.frame = frame
    print(frame)

    let indexPath = self.tableView.indexPathForView(textView)
    print(inputActive,indexPath)

    self.tableView.indexPathForView(inputActive)
    self.tableView.rowHeight = frame.size.height
}

【问题讨论】:

标签: ios swift uitableview textview row-height


【解决方案1】:

当您使用interfaceBuilder直接将单元格设计为原型单元格或xib时,实现动态单元格高度非常容易,您只需正确设置顶部和底部约束,其余的事情由tableViewAutoDimension完成。

override func viewDidLoad() {
  super.viewDidLoad()
  tableView.estimatedRowHeight = 50
  tableView.rowHeight = UITableViewAutomaticDimension
}

【讨论】:

  • 哦,好吧,这可以与用户添加数据行的 textview 一起使用吗?
  • @JeremyAndrews 如果你使用 textview 那么它工作正常。如果有任何问题,请尝试一次,然后发表评论。
  • 将尝试需要设计一个单元 - 将发布结果
  • 对于 textView,它的设计方式是每当用户输入的内容超过 textView 的高度时,内容就会开始滚动,因此单元格高度可能不会动态变化。如果您在标签中显示内容并将行数设置为 0,那么单元格的大小肯定会改变。继续尝试并分享您的发现。
【解决方案2】:

使用sizeToFit 根据您的内容(文本)大小设置UITextview 高度并在cellForRowAtIndexPath 中启用translatesAutoresizingMaskIntoConstraints

试试这个看看

class TextViewCell: UITableViewCell {

    @IBOutlet weak var textview: UITextView!


    func adjustTextViewHeight(textview : UITextView) {
        textview.translatesAutoresizingMaskIntoConstraints = true
        textview.sizeToFit()
        textview.isScrollEnabled = false
    }
}


class TableController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var table: UITableView!


    override func viewDidLoad() {
        super.viewDidLoad()

        // Don't forget to set dataSource and delegate for table
        table.dataSource = self
        table.delegate = self

        // Set automatic dimensions for row height
        table.rowHeight = UITableViewAutomaticDimension
        table.estimatedRowHeight = UITableViewAutomaticDimension
    }



    // UITableViewAutomaticDimension calculates height of label contents/text
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "textview") as! TextViewCell
        cell.adjustTextViewHeight(textview: cell.textview)
        return cell
    }

}

这是故事板布局:

结果如下:

【讨论】:

  • 看起来不错 - 尝试后会发布 - 我唯一不同的是我有很多部分,但这不重要。
  • 我复制了您的示例,并且行会调整为已在 textview 中的文本大小,但不会即时调整文本内容的更改。我已经使用了表格之外的文本视图,让它们根据内容进行扩展 - 只是无法在表格视图中得到它。
  • table.reloadData() 的工作是什么,但这不是解决方案。所以真正需要的是当内容超过 textview 框架大小时 table.reloadData() 。明显的问题是每次都降低键盘,所以它不是正确的解决方案
【解决方案3】:

“Krunal”的答案缺少一两块......

从单元格布局/约束开始:

并使用此代码:

import UIKit

class WithTextViewCell: UITableViewCell, UITextViewDelegate {

    @IBOutlet var theTextView: UITextView!

    var callBack: ((UITextView) -> ())?

    override func awakeFromNib() {
        super.awakeFromNib()
        // in case these were not set in IB
        theTextView.delegate = self
        theTextView.isScrollEnabled = false
    }

    func textViewDidChange(_ textView: UITextView) {
        // tell controller the text changed
        callBack?(textView)
    }

}

class TableWithTextViewTableViewController: UITableViewController {

    var cellData = [
        "UITableViewController implements the following behaviors:",
        "If a nib file is specified via the init(nibName:bundle:) method (which is declared by the superclass UIViewController), UITableViewController loads the table view archived in the nib file. Otherwise, it creates an unconfigured UITableView object with the correct dimensions and autoresize mask. You can access this view through the tableView property.",
        "If a nib file containing the table view is loaded, the data source and delegate become those objects defined in the nib file (if any). If no nib file is specified or if the nib file defines no data source or delegate, UITableViewController sets the data source and the delegate of the table view to self.",
        "When the table view is about to appear the first time it’s loaded, the table-view controller reloads the table view’s data. It also clears its selection (with or without animation, depending on the request) every time the table view is displayed. The UITableViewController class implements this in the superclass method viewWillAppear(_:). You can disable this behavior by changing the value in the clearsSelectionOnViewWillAppear property.",
        "When the table view has appeared, the controller flashes the table view’s scroll indicators. The UITableViewController class implements this in the superclass method viewDidAppear(_:).",
        "It implements the superclass method setEditing(_:animated:) so that if a user taps an Edit|Done button in the navigation bar, the controller toggles the edit mode of the table.",
        "You create a custom subclass of UITableViewController for each table view that you want to manage. When you initialize the controller in init(style:), you must specify the style of the table view (plain or grouped) that the controller is to manage. Because the initially created table view is without table dimensions (that is, number of sections and number of rows per section) or content, the table view’s data source and delegate—that is, the UITableViewController object itself—must provide the table dimensions, the cell content, and any desired configurations (as usual). You may override loadView() or any other superclass method, but if you do be sure to invoke the superclass implementation of the method, usually as the first method call.",
        ]

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 100

    }

    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return cellData.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "WithTextViewCell", for: indexPath) as! WithTextViewCell

        // Configure the cell...
        cell.theTextView.text = cellData[indexPath.row]

        cell.callBack = {
            textView in
            // update data source
            self.cellData[indexPath.row] = textView.text
            // tell table view we're starting layout updates
            tableView.beginUpdates()
            // get current content offset
            var scOffset = tableView.contentOffset
            // get current text view height
            let tvHeight = textView.frame.size.height
            // telll text view to size itself
            textView.sizeToFit()
            // get the difference between previous height and new height (if word-wrap or newline change)
            let yDiff = textView.frame.size.height - tvHeight
            // adjust content offset
            scOffset.y += yDiff
            // update table content offset so edit caret is not covered by keyboard
            tableView.contentOffset = scOffset
            // tell table view to apply layout updates
            tableView.endUpdates()
        }

        return cell
    }

}

“关键”部分:

  1. 向您的单元格添加一个“回调”闭包,以便我们可以在文本发生更改时通知控制器。

  2. 当回调发生时,让表视图控制器:用编辑过的文本更新数据源;告诉文本视图调整自身大小;并调整内容偏移以避免插入符号(文本插入点)消失在键盘后面。

【讨论】:

  • 非常感谢 - 我所做的唯一更改是我可以使用 ViewController ISO 和 TableViewController。除此之外,它完美无缺。我只需要添加代码来为键盘向上滚动表格,但我有代码
猜你喜欢
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多