NSLayoutContraints在UITableViewController上应用不一致(显然)

时间:2018-05-02 19:22:56

标签: uitableview ios11 nslayoutconstraint

我试图在UITableViewController上添加某种叠加菜单。我的第一个目标是在非常贫瘠的控制器上显示屏幕底部的背景视图。我是以编程方式使用以下代码在条形按钮的回调中执行此操作,即在原始布局发生后调用:

    print("self.tableView.frame=\(self.tableView.frame)")
    let settingsView = UIView()
    settingsView.translatesAutoresizingMaskIntoConstraints = false
    settingsView.backgroundColor = UIColor.cyan.withAlphaComponent(0.5)
    self.view.addSubview(settingsView)
    self.view.addConstraints([
        NSLayoutConstraint(item: settingsView, attribute: .bottom, relatedBy: .equal, toItem: self.tableView, attribute: .bottom, multiplier: 1, constant: 50),
        NSLayoutConstraint(item: settingsView, attribute: .leading, relatedBy: .equal, toItem: self.tableView, attribute: .leading, multiplier: 1, constant: 0),
        NSLayoutConstraint(item: settingsView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: self.view.frame.width),
        //NSLayoutConstraint(item: settingsView, attribute: .trailing, relatedBy: .equal, toItem: self.tableView, attribute: .trailing, multiplier: 1, constant: 0),
        NSLayoutConstraint(item: settingsView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 100)
        ])
    self.view.setNeedsLayout()

但结果并不像我预期的那样:我的视图底部实际上与顶部边距对齐(因此50值可以看到它,而不是位于屏幕的底部戳穿,您可以通过附图中的导航栏看到青色。这是为什么?如果我改变第一个约束来对齐顶部而不是底部,它可以正常工作(但当然在顶部)。

另外,我很惊讶我必须更换我的第四个约束(被注释掉的那个,据说是将视图的右边缘与屏幕的右边缘对齐)与第三个约束(其中设置宽度,但不知何故似乎不太干净)。如果我使用第四个,那么视图就会完全消失(我猜测它的宽度为0)。原因是什么?

开头的print命令可确保tableView的大小合适:

self.tableView.frame=(0.0, 0.0, 375.0, 667.0)

这一切似乎微不足道,所以我肯定没有在这里看到......

screenshot

1 个答案:

答案 0 :(得分:0)

所以这里的问题似乎真的是UITableView(Controller),因为这些约束适用于普通的UIView(Controller)。它周围的UINavigationController在这里没有发挥作用。出于某种原因,似乎.bottom.trailing锚点不能用于表格视图 - 如果有人知道为什么或可以向我解释如何操作,请执行!

无论如何,我通过使用视图的实际测量来解决这个问题,这是正确的。所以第一个约束变为:

NSLayoutConstraint(item: settingsView, 
    attribute: .bottom, 
    relatedBy: .equal, 
    toItem: self.view, 
    attribute: .top, 
    multiplier: 1, 
    constant: self.view.frame.height + self.view.bounds.minY)

这使视图很好地显示在屏幕的底部。常量中的self.view.bounds.minY说明了屏幕顶部是否存在导航栏。仍感觉有点像" hack"对我来说,特别是因为我不明白为什么其他版本不起作用。