当我从一个我猜到的视图控制器返回时,为什么我的UITableView的格式完全出错?

时间:2014-10-28 14:07:14

标签: ios objective-c uitableview uiviewcontroller autolayout

我有一个带有自定义单元格的UITableView,其中有一些标签可以动态决定单元格的高度。当我点击一个单元格并切换到一个新的视图控制器时,返回时,单元格的所有格式都完全搞砸了,我无法弄清楚导致它的原因。

这是细胞通常的样子:

enter image description here

我对它们设置了一些非常基本的约束。顶部标签固定在顶部和左侧边距上,并且必须始终从右侧开始> = 20。其他标签与第一个标签的左侧对齐,并在所有标签之间设置垂直间距。中间标签对边距有正确的间距约束,底部标签与第一个标签的基线对齐,并且所有标签之间都有水平间距。

当我回到这个表视图时,它看起来像这样:

enter image description here

我无法弄清楚导致它布局的方式与我离开时不同。如果我滚动它似乎"重置"他们回到应有的状态,但在最初的负荷下,他们真的搞砸了。如果需要,我可以附加项目,但在故事板之外真的不多。

cellForRowAtIndexPath:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomTableViewCell

    let object = objects[indexPath.row]

    cell.title1.text = object.name
    cell.title2.text = object.color
    cell.title3.text = object.roar

    return cell
}

示例项目: http://cl.ly/040L2z0q0V2d

5 个答案:

答案 0 :(得分:3)

当从segue返回时,表视图单元格似乎不会根据内容调整大小。使用示例项目,我在viewWillAppear中抛出了一个重载数据,这似乎解决了这个问题。

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.tableView.reloadData()
}

答案 1 :(得分:2)

您的项目实际上存在几个问题。

数据加载自动布局

第一个是在使用数据绘制单元格时导致奇怪的行为。从segue展开时,您会在模糊的布局计算中看到桌面上的其他单元格。

解决方案 :将数据移至override func viewWillAppear(animated: Bool) {并执行tableView.reloadData() (正如@rFessler正确建议的那样)

另一方面, Autolayout 是一种火热的野兽。 可驯服的。值得进一步研究这个话题。我无法通过自动调整单元格高度使您的布局工作,但我会为您留下一些参考和项目。


<强> 参考文献:

http://www.appcoda.com/self-sizing-cells/

http://captechconsulting.com/blog/tyler-tillage/ios-8-tutorial-series-auto-sizing-table-cells


<强> 项目: http://cl.ly/3z3a2Z3a3U2K

答案 2 :(得分:1)

我玩这个并找到一个简单的解决方案,添加这似乎可以解决问题。

override func viewWillDisappear(animated:Bool) {
    super.viewWillDisappear(animated)
    self.tableView.estimatedRowHeight = 166.0
}

答案 3 :(得分:1)

我自己也有过类似的问题。我下载了你的项目,似乎我通过删除和调整一些约束来解决它。这就是我的约束现在的样子:

enter image description here

此外,我已将此添加到viewDidLoad:

self.tableView.estimatedRowHeight = 120
self.tableView.rowHeight = UITableViewAutomaticDimension

我还添加了这个以测试删除:

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == .Delete
    {
        self.objects.removeAtIndex(indexPath.row)

        self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
    }
}

现在您甚至可以旋转设备并删除行,而且它们都非常出色!


但是,如果您在导航控制器上推送此视图仍然存在问题(这是我的问题在开始时)。请参阅下面的故事板以获得一些时髦的标签:

enter image description here

要解决这个问题,我们实际上似乎必须做一个黑客攻击! (该死的你,苹果,这是怎么回事?!)

var firstAppearance=true
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    if firstAppearance
    {
        if let indexPaths = self.tableView.indexPathsForVisibleRows()
        {
            self.tableView.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.None)
            self.firstAppearance = false
        }
    }
}

目前,我认为这是最好的。

答案 4 :(得分:0)

由于方法tableView:estimatedHeightForRowAtIndexPath将在每次转换到新的MVC时被调用,并且更改自动布局,您可以这样做

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

重复使用自动布局