以编程方式添加标签,与Storyboard中的标签对齐

use*_*173 5 uitableview ios autolayout ios9 swift2

期望的观点:

在此输入图像描述

在Storyboard中,我有两个标签,其中包含我在Autolayout中创建的蓝色背景.他们的立场永远不会改变.接下来,我想cellForRowAtIndexPath在蓝色背景标签下面的代码中添加1到10个标签.

我正在努力将代码中添加的标签(棕色背景)与在Autolayout(蓝色背景)中创建的标签对齐.

以下是我失败的尝试:

在此输入图像描述

失败的两种方法:

  1. cellForRowAtIndexPath得到"B自动版式静态标签"的框架和使用动态标注的X位置.不工作.

  2. 添加约束也不起作用 - 也许我没有正确添加约束.

这是代码:

class TableViewController: UITableViewController {

    var cellHeight = [Int: CGFloat]()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.estimatedRowHeight = 85.0
        self.tableView.rowHeight = UITableViewAutomaticDimension
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

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


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
        let xLocation = cell.labelBStatic.frame.origin.x
        var yLocation = cell.labelBStatic.frame.origin.y
        let height = cell.labelBStatic.frame.size.height

        var startYLocation = yLocation + height + 20
        var i = 0
        if indexPath.row % 2 == 0 {
            i = 5
        } else {
            i = 7
        }

        while i < 10 {
            let aLabel = UILabel()
            aLabel.backgroundColor = UIColor.orangeColor()
            aLabel.text = "Label # \(i)"
            cell.contentView.addSubview(aLabel)
            addConstraints(aLabel, verticalSpacing: startYLocation)
            startYLocation += 20
            i++
        }

        print(startYLocation)
        cellHeight[indexPath.row] = startYLocation
        return cell
    }

    func addConstraints(labelView: UILabel, verticalSpacing: CGFloat) {
        // set Autoresizing Mask to false
        labelView.translatesAutoresizingMaskIntoConstraints = false

        //make dictionary for views
        let viewsDictionary = ["view1": labelView]

        //sizing constraints
        let view1_constraint_H:Array = NSLayoutConstraint.constraintsWithVisualFormat("H:[view1(>=50)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewsDictionary)

        labelView.addConstraints(view1_constraint_H)

        //position constraints
        let view_constraint_H:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("H:|-15-[view1]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewsDictionary)
        let view_constraint_V:NSArray = NSLayoutConstraint.constraintsWithVisualFormat("V:|-\(verticalSpacing)-[view1]", options: NSLayoutFormatOptions.AlignAllLeading, metrics: nil, views: viewsDictionary)

        view.addConstraints(view_constraint_H as! [NSLayoutConstraint])
        view.addConstraints(view_constraint_V as! [NSLayoutConstraint])

    }

        override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        if let height = cellHeight[indexPath.row] {
            return height
        }
        return 0
    }
Run Code Online (Sandbox Code Playgroud)

下面是Storyboard设置(两个标签都水平居中):

在此输入图像描述

问题:如何让我创建的动态标签与我创建的cellForRowAtIndexPath静态标签保持一致,Storyboard以匹配我想要的顶部视图?

Bha*_*odi 4

只是出于演示目的,我以编程方式添加了一个标签,您可以添加任意数量的标签,只需正确添加约束即可,您还需要向单元格内的最后一个标签添加 BottomSpace 约束,以便您的单元格将根据标签高度。

按照我所做的步骤来实现你想要的:

  1. 如果您已子类化 UITableViewCell 并创建了outlet,请使用 tag 或outlet 访问cellForRowAtIndexPath: 中的B AutoLayout 静态标签。

    let labelBAutolayoutStaticLabel = cell?.viewWithTag(20)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 以编程方式创建标签,如下所示,并将translatesAutoresizingMaskIntoConstraints 设置为 false,

    let labelDynamicLabel = UILabel()
    labelDynamicLabel.backgroundColor = UIColor.orangeColor()
    labelDynamicLabel.text = "A Dynamic Label"
    labelDynamicLabel.translatesAutoresizingMaskIntoConstraints = false
    cell?.contentView.addSubview(labelDynamicLabel)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您需要创建两个约束,一个是 TopSpace,第二个是leadingSpace,如下所示,

    let leadingSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: labelDynamicLabel, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: labelBAutolayoutStaticLabel, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: 0);
    
    let topSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: labelDynamicLabel, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: labelBAutolayoutStaticLabel, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 10); //Constant is the spacing between
    
    Run Code Online (Sandbox Code Playgroud)
  4. 将约束添加到单元格的 contentView 中,如下所示,

    cell?.contentView.addConstraint(leadingSpaceConstraint)
    cell?.contentView.addConstraint(topSpaceConstraint)
    
    Run Code Online (Sandbox Code Playgroud)

就是这样。

这是结果,

在此输入图像描述

以下是 cellForRowAtIndexPath 的完整代码:

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

    let labelBAutolayoutStaticLabel = cell?.viewWithTag(20)


    let labelDynamicLabel = UILabel()
    labelDynamicLabel.backgroundColor = UIColor.orangeColor()
    labelDynamicLabel.text = "A Dynamic Label"
    labelDynamicLabel.translatesAutoresizingMaskIntoConstraints = false
    cell?.contentView.addSubview(labelDynamicLabel)

    let leadingSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: labelDynamicLabel, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: labelBAutolayoutStaticLabel, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: 0);

    let topSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: labelDynamicLabel, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: labelBAutolayoutStaticLabel, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 10);

    cell?.contentView.addConstraint(leadingSpaceConstraint)
    cell?.contentView.addConstraint(topSpaceConstraint)

    return cell!
}
Run Code Online (Sandbox Code Playgroud)

编辑/更新:

如果必须将 BottomSpace 约束设置为最后一个标签(位于单元格底部的标签),有两种方法

  1. 使用 NSLayoutConstraint 如下:

    let bottomSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: labelDynamicLabel, attribute: NSLayoutAttribute.BottomMargin, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1, constant: -8)
    
    cell.contentView.addConstraint(bottomSpaceConstraint)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用如下视觉格式语言,

    let views = ["cell": cell, "labelDynamicLabel": labelDynamicLabel, "labelBAutolayoutStaticLabel": labelBAutolayoutStaticLabel]
    
    let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[labelBAutolayoutStaticLabel]-[labelDynamicLabel]-|", options: [], metrics: nil, views: views)
    
    cell.contentView.addConstraints(verticalConstraints)
    
    Run Code Online (Sandbox Code Playgroud)

如果使用 VFL 设置约束,请确保删除 topSpaceConstraint

//cell.contentView.addConstraint(topSpaceConstraint)
Run Code Online (Sandbox Code Playgroud)

这个“V:[labelBAutolayoutStaticLabel]-[labelDynamicLabel]-|”是什么 字符串的平均值是,

  1. labelDynamicLabel 应该具有到 labelBAutolayoutStaticLabel 的顶部空间(标准间距(8 点)),而 labelDynamicLabel 应该具有到 SuperView 的底部空间(标准间距)。('-|'表示给superView的标准空间)