当共享父视图嵌入导航控制器时,两个垂直对齐的视图会以不同方式开始

时间:2016-06-10 08:37:22

标签: ios autolayout

我在视图控制器中有两个表视图,视图控制器嵌入在导航控制器中。

我已垂直添加以下约束,我希望两个表视图从导航栏底部附近的同一点开始。

constraints.append(t1.topAnchor.constraintEqualToAnchor(self.topLayoutGuide.bottomAnchor, constant: 8.0))
constraints.append(t1.bottomAnchor.constraintEqualToAnchor(self.bottomLayoutGuide.topAnchor, constant: -8.0))
constraints.append(t2.topAnchor.constraintEqualToAnchor(t1.topAnchor))
constraints.append(t2.bottomAnchor.constraintEqualToAnchor(t1.bottomAnchor))

然而,事实证明,表格视图t1的启动远低于表格视图t2,后者会按预期在导航栏底部附近开始。

为什么会这样?如何解决这个问题?

更新

约束:

t1.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "cell")
t2.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "cell")

t1.dataSource = self
t2.dataSource = self

self.view.addSubview(t1)
self.view.addSubview(t2)

t1.translatesAutoresizingMaskIntoConstraints = false
t2.translatesAutoresizingMaskIntoConstraints = false

var constraints = [NSLayoutConstraint]()

constraints.append(t1.topAnchor.constraintEqualToAnchor(self.topLayoutGuide.bottomAnchor, constant: 8.0))
constraints.append(t1.bottomAnchor.constraintEqualToAnchor(self.bottomLayoutGuide.topAnchor, constant: -8.0))
constraints.append(t2.topAnchor.constraintEqualToAnchor(t1.topAnchor))
constraints.append(t2.bottomAnchor.constraintEqualToAnchor(t1.bottomAnchor))

constraints.append(t1.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor, constant: 8.0))
constraints.append(t2.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor, constant: -8.0))
constraints.append(t2.leadingAnchor.constraintEqualToAnchor(t1.trailingAnchor, constant: 8.0))
constraints.append(t1.widthAnchor.constraintEqualToAnchor(t2.widthAnchor))

NSLayoutConstraint.activateConstraints(constraints)

数据来源:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
    cell.textLabel?.text = "Start"
    return cell
}

意外的对齐:

enter image description here

2 个答案:

答案 0 :(得分:2)

只是试图复制这个问题。 如果我使用下面的代码,表视图将完全对齐。刚刚在视图控制器中添加了约束。

t1.backgroundColor = UIColor.redColor()
t2.backgroundColor = UIColor.blueColor()

view.addSubview(t1)
view.addSubview(t2)

t1.translatesAutoresizingMaskIntoConstraints = false
t2.translatesAutoresizingMaskIntoConstraints = false

view.addConstraint(t1.leftAnchor.constraintEqualToAnchor(view.leftAnchor, constant: 0.0))
view.addConstraint(t2.rightAnchor.constraintEqualToAnchor(view.rightAnchor, constant: 0.0))

t1.addConstraint(NSLayoutConstraint(item: t1, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 100.0))
t2.addConstraint(NSLayoutConstraint(item: t2, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 100.0))


view.addConstraint(t1.topAnchor.constraintEqualToAnchor(topLayoutGuide.bottomAnchor, constant: 8.0))
view.addConstraint(t1.bottomAnchor.constraintEqualToAnchor(bottomLayoutGuide.topAnchor, constant: -8.0))
view.addConstraint(t2.topAnchor.constraintEqualToAnchor(t1.topAnchor))
view.addConstraint(t2.bottomAnchor.constraintEqualToAnchor(t1.bottomAnchor))

请给我这个布局:

enter image description here

也许您可以更深入地了解整个布局代码?

<强>更新

使用您提供的布局代码调查问题后: 表格视图与预期完全一致。问题在于 contentInset

为某些控制台日志添加此内容:

 override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    print("Insets t1 -> \(t1.contentInset)")
    print("Insets t2 -> \(t2.contentInset)")
 }

打印出来:

Insets t1 -> UIEdgeInsets(top: 64.0, left: 0.0, bottom: 0.0, right: 0.0)
Insets t2 -> UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)

Interface Builder中有一个名为调整滚动视图插入的视图控制器的选项。禁用它(或在代码中使用automaticallyAdjustsScrollViewInsets = false。)

一般情况下,表格视图(如表视图控制器中所示)位于导航栏下方(因此您可以获得模糊滚动效果...)但设置了内容插入,以便您的第一个单元格位于导航栏下方。 要在引用顶部布局指南时避免此行为,您必须禁用此选项。另一个表视图不受影响,因为它只引用另一个表的布局约束。

为视图着色总是非常有用,因此您可以查看错位是否来自您的布局代码或任何其他副作用。 (或者使用Xcode的视图调试器)

所以在设置了标志后,它会从中获取:

enter image description here

到此:

enter image description here

干杯
奥兰多

答案 1 :(得分:1)

修改一行代码就可以解决它。

替换

NSLayoutConstraint.activateConstraints(constraints)

self.view.addConstraints(constraints)

我认为你完全不了解Auto Layout的概念。

更新:

很抱歉,我并不是指UINavigationController。 UIViewController默认调整scrollview的插图,你可以通过 automaticAdjustsScrollViewInsets = false 来阻止它。

顺便说一句,您可以使用Mansory或Purelayout轻松设置约束。

class ViewController: UIViewController, UITableViewDataSource {

var t1: UITableView = UITableView(frame: CGRectZero, style: .Plain)
var t2: UITableView = UITableView(frame: CGRectZero, style: .Plain)

override func viewDidLoad() {
    super.viewDidLoad()

    // This line is the point.
    automaticallyAdjustsScrollViewInsets = false
    commonInit()
}

func commonInit(){
    view.backgroundColor = UIColor .whiteColor()
    t1.backgroundColor = UIColor.blueColor()
    t2.backgroundColor = UIColor.greenColor()

    view.addSubview(t1)
    view.addSubview(t2)

    t1.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "cell")
    t2.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "cell")

    t1.dataSource = self
    t2.dataSource = self

    self.view.addSubview(t1)
    self.view.addSubview(t2)

    t1.translatesAutoresizingMaskIntoConstraints = false
    t2.translatesAutoresizingMaskIntoConstraints = false

    var constraints = [NSLayoutConstraint]()

    constraints.append(t1.topAnchor.constraintEqualToAnchor(self.topLayoutGuide.bottomAnchor, constant: 8.0))
    constraints.append(t1.bottomAnchor.constraintEqualToAnchor(self.bottomLayoutGuide.topAnchor, constant: -8.0))
    constraints.append(t2.topAnchor.constraintEqualToAnchor(t1.topAnchor))
    constraints.append(t2.bottomAnchor.constraintEqualToAnchor(t1.bottomAnchor))

    constraints.append(t1.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor, constant: 8.0))
    constraints.append(t2.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor, constant: -8.0))
    constraints.append(t2.leadingAnchor.constraintEqualToAnchor(t1.trailingAnchor, constant: 8.0))
    constraints.append(t1.widthAnchor.constraintEqualToAnchor(t2.widthAnchor))

    view.addConstraints(constraints)
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
    cell.textLabel?.text = "Start"
    return cell
}
}