当前位置: 首页 > 知识库问答 >
问题:

自动调整(动态高度)表格视图单元格大小的问题

傅茂实
2023-03-14

我在UIViewController中有一个UITableView作为视图的一部分。我正在尝试根据文本的长度自动调整表格单元格的大小。它不会设置textview的文本,单元格将以idCellTextView单元格的标准高度结束。我已经四处搜索过,正在尝试从单元格内的文本视图相对于内容视图和代码在自动布局中使用固定,如下所示:

tableView.estimatedRowHeight = 70
tableView.rowHeight = UITableViewAutomaticDimension

与问题相关的视图控制器的其余部分显示在以下位置:

class ExperimentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextViewDelegate {
var expId: String = ""
let experimentDescription: String = ""
var cellDescriptors: NSMutableArray!
var visibleRowsPerSection = [[Int]]()


let notificationCenter = NotificationCenter.default

override func viewDidLoad() {
    super.viewDidLoad()


    //TABLE CELLS
    loadCellDescriptors()
    tableView.tableFooterView = UIView()
    tableView.layoutMargins = UIEdgeInsets.zero
    tableView.separatorInset = UIEdgeInsets.zero
    tableView.delegate = self
    tableView.dataSource = self
    tableView.isHidden = true
    tableView.estimatedRowHeight = 70
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")
    tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "idCellNormal")
    tableView.register(UINib(nibName: "HintCell", bundle: nil), forCellReuseIdentifier: "idCellTextView")


    //ADD VIEWS
    baseView.addSubview(backgroundImage)
    baseView.addSubview(foregroundImage)
    baseView.addSubview(nameLabel)
    baseView.addSubview(segmentedController)
    baseView.addSubview(descriptionText)
    baseView.addSubview(hint)
    baseView.addSubview(tableView)

}



/*
 Get property list for the different cells we want to have in the hint table
 */
func loadCellDescriptors() {
    if let path = Bundle.main.path(forResource: "CellDescriptor", ofType: "plist") {
        cellDescriptors = NSMutableArray(contentsOfFile: path)
        getIndicesOfVisibleRows()
        tableView.reloadData()
    }
}

/*
 Returns number of rows in a given section
 */
func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
    return visibleRowsPerSection[section].count
}

/*
 Returns number of sections in table
 */
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    /*if cellDescriptors != nil {
        return cellDescriptors.count
    }
    else {
        return 0
    }*/
    print(items.count)
    return 3
}

/*
 Sets up the cell contents
 */
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath)
    let cell = tableView.dequeueReusableCell(withIdentifier: currentCellDescriptor["cellIdentifier"] as! String , for: indexPath) as! CustomCell

    if currentCellDescriptor["cellIdentifier"] as! String == "idCellNormal" {
        print("1")
        if currentCellDescriptor["primaryTitle"] != nil {
            cell.labelOfRow.text = "Hintet er"
            cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
        }
    } else if currentCellDescriptor["cellIdentifier"] as! String == "idCellTextView" {

        cell.textView.delegate = self
        cell.textView.isEditable = false
        cell.textView.isSelectable = false
        cell.textView.isScrollEnabled = true
        cell.textView.text = "orem Ipsum er rett og slett dummytekst fra og for trykkeindustrien. Lorem Ipsum har vært bransjens standard for dummytekst helt siden 1500-tallet, da en ukjent boktrykker stokket en mengde bokstaver for å lage et prøveeksemplar av en bok. Lorem Ipsum har tålt tidens tann usedvanlig godt, og har i tillegg til å bestå gjennom fem århundrer også tålt spranget over til elektronisk typografi uten vesentlige endringer. Lorem Ipsum ble gjort allment kjent i 1960-årene ved lanseringen av Letraset-ark med avsnitt fra Lorem Ipsum, og senere med sideombrekkingsprogrammet Aldus PageMaker som tok i bruk nettopp Lorem Ipsum for dummytekst.orem Ipsum er rett og slett dummytekst fra og f"
    }
    cell.layoutMargins = UIEdgeInsets.zero

    return cell
}

/*
 Handles row selections
 Finds the index of the cell that was selected, checks if it is/can be expanded and animates in the additional rows
 */
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let indexOfTappedRow = visibleRowsPerSection[indexPath.section][indexPath.row]
    let cellDescriptor = cellDescriptors[indexPath.section] as! NSMutableArray
    let cell = (cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfTappedRow]
    var shouldExpandAndShowSubRows: Bool = false

    //Checks if cell is expandable, if it is we check if cell isn't already expanded. If it isn't we can expand the cell
    if (cell as AnyObject)["isExpandable"] as! Bool == true {
        shouldExpandAndShowSubRows = false
        if (cell as AnyObject)["isExpanded"] as! Bool == false {
            shouldExpandAndShowSubRows = true
        }
    }

    (cell as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isExpanded")

    //Makes the cells inside the specific section visible
    for i in (indexOfTappedRow + 1)...(indexOfTappedRow + ((cell as AnyObject)["additionalRows"] as! Int)) {
        (cellDescriptor[i] as AnyObject).setValue(shouldExpandAndShowSubRows, forKey: "isVisible")
    }

    //Update the overview of the currently visible rows
    getIndicesOfVisibleRows()
    //Reload the sections to see the changes
    tableView.reloadSections(NSIndexSet(index: indexPath.section) as IndexSet, with: UITableViewRowAnimation.fade)
}

/*
 Get overview of the rows that are currently visible
 */
func getIndicesOfVisibleRows() {
    visibleRowsPerSection.removeAll()

    for currentSectionCells in cellDescriptors.objectEnumerator().allObjects as! [[[String:AnyObject]]] {
        var visibleRows = [Int]()

        for row in 0...((currentSectionCells).count - 1) {
            if currentSectionCells[row]["isVisible"] as! Bool == true {
                visibleRows.append(row)
            }
        }

        visibleRowsPerSection.append(visibleRows)
    }
}

/*
 Get cell descriptor from file for specific cell
 */
func getCellDescriptorForIndexPath(_ indexPath: IndexPath) -> [String: AnyObject] {
    let indexOfVisibleRow = visibleRowsPerSection[indexPath.section][indexPath.row]
    let cellDescriptor = (cellDescriptors[indexPath.section] as! NSMutableArray)[indexOfVisibleRow] as! [String: AnyObject]
    return cellDescriptor
}
}

共有3个答案

曾修真
2023-03-14

我建议使用AutoLayout而不是自动调整大小。设计UI元素既简单又好。以下步骤将帮助您如何使用AutoLayout设计自动调整大小的单元格。

设置行高的自动尺寸

  • 分配和实施数据源和委派
  • UITableView自动维度指定为行高度

-

@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
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



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

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

对于UITableviewCell中的标签实例

  • 设置的行数 = 0 (
高建本
2023-03-14

试试这个 -

确保首先在表视图单元格中正确添加约束。

然后从故事板的属性检查器部分设置UILable的这两个属性:

1-行到0

2-换行符到自动换行

注意-不要固定UILable的高度。

对于文本视图-

你需要禁用滚动。它会工作的。

薛华奥
2023-03-14

试试这个:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

这里举例

 类似资料:
  • 场景- > TableView高度是使用纵横比相对于superview的高度动态设置的。 TableViewCell的高度是根据表格视图的高度计算的: 问题 - 最初在委托方法中没有正确计算表格视图高度。但在滚动单元格后正确计算。 尝试的解决方案: 在视图中重新加载。 调用 在单元格中进行. 有什么方法可以正确计算出这个表格的高度吗?

  • 我有一个带有一堆单元格的表视图(自定义单元格,它只有它的内容视图)。 在 中,我正在向自定义单元格的content视图添加一个预定义的UIView(它有几个子视图)。我之前为UIView及其子视图设置了所有约束。 最后但并非最不重要的是,我为我的自定义单元格的内容视图(superview)和UIView设置了垂直和水平约束,UIView是在(subview)之前添加的。 约束字符串如下所示: 不幸

  • 我有一个具有动态高度的表视图与其他具有动态高度的UI组件一起在表视图中 数据,模型在这里.. 单元格子视图。。 这是内部tableView及其约束! 构造器

  • 我正在使用带有Autolayout和UICollectionView的自动调整单元格。 我可以在单元初始化代码中指定约束: 但是,应用会崩溃,因为单元格尚未添加到。 问题 > 在生命周期的哪个阶段,可以添加具有 的< code>width集合视图< code >的widthUIScreenUIWindow '的实例吗? 编辑问题不是重复的,因为它不是关于如何使用自动调整单元格大小功能,而是关于在使

  • 问题内容: 在我的应用程序中,我有一个表格视图,每个单元格中都有一个图像,标签和文本视图。我希望能够根据文本视图中的内容量自动调整单元格的大小。(文本视图是最下面的文本。) 到目前为止,我已经添加了正确的约束。文本视图的前导,尾随,顶部和底部,并且已禁用滚动和编辑。 在我的tableViewController.swift文件中,我编写了以下代码: 但是,这不起作用,因为当我在文本视图中添加更多文

  • 我正在尝试实现这个功能: 在表视图的每个单元格中显示标题、说明和图像。但是,图像可能为零。要求是: 当image为nil时,自动展开标签以适应整个单元格 Tableview单元格高度应根据描述标签自动调整。 需要使用stackView 我以编程方式做到了这一点: > 设置此为tableview: 创建2个堆栈视图:一个用于标签,一个用于标签图像: 然而,这段代码不会自动调整tableview单元格