自动调整大小(动态高度)表格视图单元格的问题
Posted
技术标签:
【中文标题】自动调整大小(动态高度)表格视图单元格的问题【英文标题】:Problems with autoresizing (dynamic height) tableview cells 【发布时间】:2017-02-17 11:49:08 【问题描述】:我在 UIViewController 中有一个 UITableView 作为视图的一部分。我正在尝试根据文本的长度自动调整表格单元格的大小。它没有设置 textview 的文本,并且单元格最终处于 idCellTextView-cell 的标准高度。我已经四处搜索并尝试在单元格内的文本视图中使用相对于内容视图和代码的自动布局中的固定,如下所示。 :
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) 方法。 textview里面的文字长度会不一样,所以是的 André UITextView 类实现了可滚动的多行文本区域的行为。因此,随着内容长度的增加,它会自行滚动。 打算使用 heightforrowatindexpath 并手动计算。谢谢你:) @André - 这解决了吗 【参考方案1】:试试这个:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
return UITableViewAutomaticDimension
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
return UITableViewAutomaticDimension
Here Example
【讨论】:
【参考方案2】:试试这个 -
确保首先在表格视图单元格中正确添加约束。
然后从情节提要的属性检查器部分设置 UILable 的这两个属性:
1 - 到 0 的行
2 - 换行换行
注意 - 不要固定 UILable 的高度。
对于 TextView -
您需要禁用滚动。它会起作用的。
【讨论】:
这是我要扩展的文本视图,而不是标签:| 对于 textview 只需添加顶部底部前导和尾随约束不固定高度..它应该工作 或者你可以附上你的手机屏幕截图我可以试试。【参考方案3】:我建议使用 AutoLayout 而不是自动调整大小。设计 UI 元素既简单又好用。以下步骤将帮助您了解如何使用 AutoLayout 设计自动调整单元格大小。
要为行高和估计行高设置自动尺寸,请确保按照以下步骤制作,自动尺寸对单元格/行高布局有效。
分配和实现 dataSource 和委托 将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(&换行模式=截尾) 设置与其父视图/单元格容器相关的所有约束(顶部、底部、左右)。 可选:设置标签的最小高度,如果你想要标签覆盖的最小垂直区域,即使标签/文本没有数据。【讨论】:
【参考方案4】:您必须将 numberOfLines
设置为 0
以允许单元格内的 UILabel 增长
【讨论】:
这是我要扩展的文本视图,而不是标签:|以上是关于自动调整大小(动态高度)表格视图单元格的问题的主要内容,如果未能解决你的问题,请参考以下文章