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

3

我在UIViewController中的视图中有一个UITableView。 我试图根据文本长度自动调整表格单元格的大小。但它不会设置textview的文本,单元格最终以idCellTextView-cell的标准高度结束。我已经搜索了一些资料,并尝试使用以下代码中textview相对于contentview的自动布局固定:

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
}
}

André,你的可扩展表视图内容是否很大,需要自动调整大小?你可以使用(heightForRowAtIndexPath)方法来代替。 - Tushar Sharma
文本视图中的文本长度会有所变化,所以是的。 - André
UITextView类实现了可滚动的多行文本区域的行为。因此,随着内容长度的增加,它会自动滚动。 - Tushar Sharma
将使用heightforrowatindexpath并手动计算。谢谢 :) - André
@André - 这个问题解决了吗? - Krunal
4个回答

1

试试这个:

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

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

这里是示例


0

尝试这个 -

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

然后从Storyboard的Attributes inspector部分设置UILable的这两个属性:

1- 行数为0

2- 换行方式为word wrap

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

对于TextView -

您需要禁用滚动。它会起作用。


我想要扩展的是TextView而不是Label :| - André
对于TextView,只需添加顶部、底部、前导和尾随约束,不要固定高度...它应该可以工作。 - Prema Janoti
你可以将你的手机截图发送给我,我可以尝试进行翻译。 - Prema Janoti

0

你必须将numberOfLines设置为0,以允许单元格内的UILabel自动增长


我想要扩展的是TextView,而不是Label :| - André

0
我建议使用AutoLayout而不是自动调整大小。它更容易和更好地设计UI元素。以下步骤将帮助您了解如何使用AutoLayout设计自动调整大小的单元格。
为行高设置自动尺寸和预估行高,请确保执行以下步骤以使自动尺寸对单元格/行高布局生效:
  • 分配并实现数据源和代理
  • UITableViewAutomaticDimension分配给rowHeight和estimatedRowHeight
  • 实现代理/数据源方法(即heightForRowAt 并返回一个值UITableViewAutomaticDimension

-

@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(并将换行模式设置为截断尾部)
  • 相对于其父视图/单元格容器设置所有约束(顶部、底部、右侧和左侧)。
  • 可选:如果您希望标签即使没有数据/文本也覆盖最小垂直区域,请设置标签的最小高度。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接