【发布时间】:2019-08-01 19:54:03
【问题描述】:
【问题讨论】:
【问题讨论】:
@BrunoPastre 是正确的,但附加也不是在数组中分配值的方法。当您向上和向下滚动时,此函数将对某些单元格运行多次。您最终会在数组的不同位置多次列出相同的宽度。
您应该创建具有正确维度的数组,然后将它们分配为cellsWidthsArray[indexPath.row] = cell.cellTextLabel.frame.size.width。
【讨论】:
您应该只创建一次数组,而不是每次调用tableView(_: UITableView, cellForRowAt: IndexPath) -> UITableViewCell。这可以通过将第 83 行的数组声明移动到函数范围之外的某个位置,但在类范围内,如第 92 行。当你这样做时,cellsWitdhsArray 将成为一个类变量,或者一个属性,可以从类内的任何地方访问
【讨论】:
该方法每个单元格调用一次,如果您声明一个局部变量 cellsWidthArray 它不会在多次调用该函数时持续存在。
您需要将此数组“保存”在不是本地临时范围的某个位置。最好的方法是将其保存为类的属性。
我可以在您的代码中看到您已经有另一个数组,它是一个属性:tableViewRowsInsideSectionsArray。向上滚动到(希望)在同一范围内的类声明的最顶部添加您自己的cellsWidthArray。
它应该看起来像
class MyViewController {
...
private var cellsWidthArray: [CGFloat] = []
...
这样,每次函数结束时本地数组都不会丢失 - 它归视图控制器所有,只要该类存在,它就可以在该类中的任何位置使用。
但是,它可能无法按您的预期工作,因为该方法的另一个问题(tableView(cellForRowAt:) 是它仅在显示单元格时调用(在屏幕上可见)。如果您滚动,它将被多次调用一个单元格在屏幕上来回切换。
您可以通过创建一个字典来解决潜在的重复问题,其中键是唯一标识单元格的东西(看起来它只是这里的文本),值是宽度。比如:
class MyViewController {
...
private var cellsWidthDictionary: [String: CGFloat] = [:]
...
func tableView(cellForRowAt:) { // I didn't feel like typing it all out
...
cellsWidthDictionary[theTextYouAreUsing] = width
但是你现在有另一个问题,你获取宽度的方式,在你设置文本之后访问标签的框架,实际上可能不正确。这个函数只是准备单元格,自动布局和框架调整可能会在以后发生。 一个简单的单行解决方案可能会尝试在标签上设置文本后强制单元格上的布局,例如:
cell.cellTextLabel.sizeToFit() 或 cell.layoutIfNeeded()
这只会调整标签的框架以完美地包裹现有内容..但更好的解决方案是实际计算它..
你可以使用https://developer.apple.com/documentation/foundation/nsstring/1531844-size 像
let labelSize = (label.text?.size(attributes: [NSFontAttributeName: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))
然后访问labelSize.width
您仍然会遇到仅在单元格即将显示在屏幕上时才调用该函数的问题。如果您将其用于调试/测试/提供信息的目的,您可以手动滚动每个单元格以构建该表。但否则你需要做其他事情......
幸运的是,Swift 有一个计算字符串大小的函数——你只需要确保你指定了文本/字体/大小/任何其他样式元素。我在上面指出了...您可以遍历所有输入到单元格中的字符串,并在获得数据后立即生成字典。
请记住,这假设为单行,如果您有标签的最大宽度或其他会导致文本被截断的约束,您需要更加明确 - 我鼓励您使用谷歌搜索如何计算如果需要,请根据您的需要确定标签的大小。
【讨论】: