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

Posted

技术标签:

【中文标题】NSLayoutContraints 在 UITableViewController 上应用不一致(显然)【英文标题】:NSLayoutContraints applied inconsistently (apparently) on UITableViewController 【发布时间】:2018-05-02 19:22:56 【问题描述】:

我正在尝试在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)

这一切似乎都很微不足道,所以肯定有一些我在这里没有看到的东西......

【问题讨论】:

【参考方案1】:

所以这里的问题似乎真的是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 说明屏幕顶部存在导航栏。对我来说仍然感觉有点像“黑客”,特别是因为我不明白为什么其他版本不起作用。

【讨论】:

以上是关于NSLayoutContraints 在 UITableViewController 上应用不一致(显然)的主要内容,如果未能解决你的问题,请参考以下文章

Swift UITapGestureRecognizer 慢

如何在 Swift 中继承 UITableViewController

滚动/调整 UITableView

在后台线程中加载 CoreData

TableView 不显示数据

UITableView 拉伸问题