以编程方式添加标签,与Storyboard中的标签对齐 [英] Adding labels programmatically, aligned with labels from Storyboard

查看:116
本文介绍了以编程方式添加标签,与Storyboard中的标签对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所需视图:





两种失败的方法:


  1. cellForRowAtIndexPath 获取B AutoLayout静态标签的框架,并使用X位置作为动态标签。没有用。


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


以下是代码:

  class TableViewController:UITableViewController { 

$ var cellHeight = [Int:CGFloat]()

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

覆盖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 {


让cell = tableView.dequeueReusableCellWithIdentifier(Cell,forIndexPath:indexPath)为! 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
}

而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
返回单元格
}

func addConstraints(labelView:UILabel,verticalSpacing:CGFloat){
//将Autoresizing Mask设置为false
labelView.translatesAutoresizingMaskIntoConstraints = false

//为视图制作字典
let viewsDictionary = [view1:labelView]

//大小限制
let view1_constraint_H:Array = NSLayoutConstraint.constraintsWithVisualFormat(H:[view1(> = 50)],选项:NSLayoutFormatOptions(rawValue:0),met rics:nil,views:viewsDictionary)

labelView.addConstraints(view1_constraint_H)

//位置约束
让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],选项:NSLayoutFormatOptions.AlignAllLeading,metrics:nil,views:viewsDictionary)

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

}

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

if let height = cellHeight [indexPath.row] {
return height
}
return 0
}

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





问题:如何获取我的动态标签我在 cellForRowAtIndexPath 中创建左对齐我在 Storyboard 中创建的静态标签,以匹配我在顶部的所需视图?

解决方案

为了演示目的,我已经以编程方式添加了一个标签,你可以添加你想要的标签,只需添加约束正确地说,您还需要将bottomSpace约束添加到单元格内的最后一个标签,以便您的单元格将根据标签h自动调整大小八。



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


  1. 访问cellForRowAtIndexPath中的B AutoLayout静态标签:如果您已经创建了UITableViewCell子类,并且创建了插座,则使用标签或插座。

      let labelBAutolayoutStaticLabel = cell?.viewWithTag(20)


  2. 以编程方式创建标签,如下所示将translatesAutoresizingMaskIntoConstraints设置为false,

      let labelDynamicLabel = UILabel()
    labelDynamicLabel.backgroundColor = UIColor.orangeColor()
    labelDynamicLabel.text =动态标签
    labelDynamicLabel.translatesAutoresizingMaskIntoConstraints = false
    cell?.contentView.addSubview(labelDynamicLabel)


  3. 您需要创建两个约束,一个用于TopSpace,第二个是LeadingSpace,如下所示,

     让leadingSpaceConstraint:NSLayoutConstraint = NSLayoutConstrai nt(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); //常量是
    之间的间距


  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,常数: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)

返回单元格!
}

编辑/更新



如果你必须将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(五:[labelBAutolayoutStaticLabel] - [labelDynamicLabel] - | options:[],metrics:nil,views:views)

    cell.contentView.addConstraints(verticalConstraints)


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

  // cell.contentView.addConstraint(topSpaceConstraint)

这是什么 V:[labelBAutolayoutStaticLabel] - [labelDynamicLabel] - |字符串均值是,


  1. labelDynamicLabel应该使用标准间距标记TopSpace到labelButolayoutStaticLabel (8pts)和labelDynamicLabel应该有标准空间SuperView的底部空间。 (' - |'表示superView的标准空间)


Desired View:

In Storyboard I have two labels with the blue background that I am creating in Autolayout. Their position will never change. Next, I would like to add anywhere from 1 to 10 labels in code in cellForRowAtIndexPath below the blue background labels.

I am struggling to align the the labels added in code (brown background) with the ones created in Autolayout (blue background).

Below is my failed attempt:

Two approaches that failed:

  1. In cellForRowAtIndexPath get the frame of "B AutoLayout Static Label" and use the X position for Dynamic Labels. Did not work.

  2. Adding constraints also did not work -- perhaps I am not adding the constraints correctly.

Here is the code:

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
    }

Below is the Storyboard setup (Both labels are centered horizontally):

Question: How can I get my dynamic labels that I am creating in cellForRowAtIndexPath left align with my static labels that were created in Storyboard to match my desired view on top?

解决方案

Just for demonstration purpose i have added one label programatically, you can add as much as labels you want, just add the constraints properly, also you need to add bottomSpace constraint to the last label inside cell so that your cell will auto resize as per the label height.

Follow the steps i have done to achieve what you want:

  1. Access the B AutoLayout Static Label in cellForRowAtIndexPath: using tag or outlet if you have subclassed UITableViewCell and have created outlet.

    let labelBAutolayoutStaticLabel = cell?.viewWithTag(20)
    

  2. Create the label programatically as below and set translatesAutoresizingMaskIntoConstraints to false,

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

  3. You need to create two constraint, one is for TopSpace and second is LeadingSpace as below,

    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. Add constraint to your cell's contentView as below,

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

That's it.

And here is the result,

Here is the full code for 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!
}

Edit/Update:

If you have to set bottomSpace constraint to the last label (label which is at bottom of cell), there are two way

  1. Use NSLayoutConstraint as below:

    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. Using Visual Format Language as below,

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

If you set constraint using VFL make sure you remove topSpaceConstraint

//cell.contentView.addConstraint(topSpaceConstraint)

What this "V:[labelBAutolayoutStaticLabel]-[labelDynamicLabel]-|" string mean is,

  1. labelDynamicLabel should have TopSpace to labelBAutolayoutStaticLabel with standardSpacing (8pts) and labelDynamicLabel should have bottom space to SuperView with standardSpacing. ('-|' indicates the standard space to superView)

这篇关于以编程方式添加标签,与Storyboard中的标签对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆