【问题标题】:Adding labels programmatically, aligned with labels from Storyboard以编程方式添加标签,与 Storyboard 中的标签对齐
【发布时间】:2016-06-24 08:35:30
【问题描述】:

所需视图:

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

我正在努力将代码中添加的标签(棕色背景)与自动布局中创建的标签(蓝色背景)对齐。

以下是我失败的尝试:

两种失败的方法:

  1. cellForRowAtIndexPath 中获取“B AutoLayout 静态标签”的框架,并将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
    }

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

问题:如何让我在 cellForRowAtIndexPath 中创建的动态标签与在 Storyboard 中创建的静态标签左对齐,以匹配我想要的顶部视图?

【问题讨论】:

    标签: ios uitableview autolayout swift2 ios9


    【解决方案1】:

    仅出于演示目的,我以编程方式添加了一个标签,您可以添加任意数量的标签,只需正确添加约束,还需要将 bottomSpace 约束添加到单元格内的最后一个标签,以便您的单元格自动调整大小根据标签高度。

    按照我已经完成的步骤来实现你想要的:

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

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

      let labelDynamicLabel = UILabel()
      labelDynamicLabel.backgroundColor = UIColor.orangeColor()
      labelDynamicLabel.text = "A Dynamic Label"
      labelDynamicLabel.translatesAutoresizingMaskIntoConstraints = false
      cell?.contentView.addSubview(labelDynamicLabel)
      
    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
      
    4. 将约束添加到单元格的 contentView 如下,

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

    就是这样。

    这是结果,

    这是 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!
    }
    

    编辑/更新:

    如果必须将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)
      
    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)
      

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

    //cell.contentView.addConstraint(topSpaceConstraint)
    

    这个 "V:[labelBAutolayoutStaticLabel]-[labelDynamicLabel]-|" 字符串是什么意思,

    1. labelDynamicLabel 应该有 TopSpace 到 labelBAutolayoutStaticLabel with standardSpacing (8pts) 并且 labelDynamicLabel 应该有底部空间到 SuperView 和 standardSpacing。 ('-|'表示superView的标准空间)

    【讨论】:

    • 谢谢。我认为这应该有效。我会在几个小时后尝试这个并报告。
    • 我以这种方式添加了底部约束let bottomSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: lastLabel, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: lastLabel.superview, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: -5); //Constant is the spacing between cell.contentView.addConstraint(bottomSpaceConstraint)这是正确的方法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 2015-09-17
    • 2011-07-07
    相关资源
    最近更新 更多