简体   繁体   中英

Centering label and UITextField inside a TableView

New to xcode/swift, spending a couple of days now trying to fix this one. Creating a universal app and having problems getting the constraint working programmatically. I would like to programmatically add a label and a UITextField inside a TableView. The label should always have a fixed width. The text field should have variable width depending on the device.

Here is what is looks like now:

在此处输入图片说明

Here is an idea of how it should look:

在此处输入图片说明

The label should be a set width. But the textfield should use the available screen.

Here is the code so far:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        // Setup Cell
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)

        // Make cell unselectable
        cell.selectionStyle = .none

        // Process Each Row
        let row = indexPath.row
        switch row
        {
        case 0:
            let label = UILabel()
            label.text = "First Name:"
            label.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(40), height: CGFloat(30))
            cell.contentView.addSubview(label)

            var textField: UITextField = UITextField()

            textField.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(170), height: CGFloat(30))

            textField.borderStyle = .roundedRect
            textField.backgroundColor = UIColor.magenta
            textField.text = "TEST"

            textField.textColor = UIColor.black
            textField.translatesAutoresizingMaskIntoConstraints = false

            cell.contentView.addSubview(textField)

            let leadingConstraint = NSLayoutConstraint(item: cell.contentView, attribute: .leftMargin, relatedBy: .equal, toItem: label, attribute: .leftMargin, multiplier: 1.0, constant: 0)
            let trailingConstraint = NSLayoutConstraint(item: cell.contentView, attribute: .rightMargin, relatedBy: .equal, toItem: textField, attribute: .rightMargin, multiplier: 1.0, constant: 0)

            cell.contentView.addConstraint(leadingConstraint)
            cell.contentView.addConstraint(trailingConstraint)

....

Please let me know if you need additional information before a downvote. Any help would be appreciated. Thanks.

Answer by UpholderOfTruth:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        // Setup Cell
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)

        // Make cell unselectable
        cell.selectionStyle = .none

        // Process Each Row
        let row = indexPath.row
        switch row
        {
        case 0:
            let label = UILabel()
            label.text = "First Name:"
            label.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(40), height: CGFloat(30))
            label.translatesAutoresizingMaskIntoConstraints = false
            cell.contentView.addSubview(label)

            var textField: UITextField = UITextField()

            textField.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(170), height: CGFloat(30))

            textField.borderStyle = .roundedRect
            textField.backgroundColor = UIColor.magenta
            textField.text = "TEST"

            textField.textColor = UIColor.black
            textField.translatesAutoresizingMaskIntoConstraints = false

            cell.contentView.addSubview(textField)

// Horizontal Constraints  
cell.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[label(==100)][textField]|", options: .init(rawValue: 0), metrics: nil, views: ["label": label, "textField": textField]))

// Vertical Constraints
cell.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: cell.contentView, attribute: .centerY, multiplier: 1, constant: 0))
cell.contentView.addConstraint(NSLayoutConstraint(item: textField, attribute: .centerY, relatedBy: .equal, toItem: cell.contentView, attribute: .centerY, multiplier: 1, constant: 0))
....

I would suggest go full auto layout and don't mix methods. So first set both view to use auto layout via setting the translatesAutoresizingMaskIntoConstraints to false.

Then either set the constraints visually like this:

cell.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[label(==100)][textField]|", options: .init(rawValue: 0), metrics: nil, views: ["label": label, "textField": textField]))

or with individual constraints like this:

cell.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .left, relatedBy: .equal, toItem: cell, attribute: .left, multiplier: 1, constant: 0))
cell.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: 100))
cell.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .right, relatedBy: .equal, toItem: textField, attribute: .left, multiplier: 1, constant: 0))
cell.contentView.addConstraint(NSLayoutConstraint(item: textField, attribute: .right, relatedBy: .equal, toItem: cell, attribute: .right, multiplier: 1, constant: 0))

Of course this just handles horiztonal positioning and sizing you need to do something about vertical positioning and sizing as well but you may be setting that up further down in your code.

Edit :

To centre vertically you can do this:

cell.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: cell.contentView, attribute: .centerY, multiplier: 1, constant: 0))
cell.contentView.addConstraint(NSLayoutConstraint(item: textField, attribute: .centerY, relatedBy: .equal, toItem: cell.contentView, attribute: .centerY, multiplier: 1, constant: 0))

Edit2 :

Combining into a single line:

cell.contentView.addConstraints([NSLayoutConstraint(item: label, attribute: .centerY, relatedBy: .equal, toItem: cell.contentView, attribute: .centerY, multiplier: 1, constant: 0), NSLayoutConstraint(item: textField, attribute: .centerY, relatedBy: .equal, toItem: cell.contentView, attribute: .centerY, multiplier: 1, constant: 0)])

Edit3 :

cell.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[label(==100)][textField]-8-|", options: .init(rawValue: 0), metrics: nil, views: ["label": label, "textField": textField]))

Change these properties:

    switch row
            {
            case 0:
            let leadingConstraint = NSLayoutConstraint(item: cell.contentView, attribute: .leftMargin, relatedBy: .equal, toItem: label, attribute: .leftMargin, multiplier: 1.0, constant: 0)
                let trailingConstraint = NSLayoutConstraint(item: cell.contentView, attribute: .rightMargin, relatedBy: .equal, toItem: textField, attribute: .rightMargin, multiplier: 1.0, constant: 0)

                cell.contentView.addConstraint(leadingConstraint)
                cell.contentView.addConstraint(trailingConstraint)

                let label = UILabel()
                label.text = "First Name:"
                //here is the trick: play with x and width. It might also be cell.contentView.size().width
                label.frame = CGRect(x: CGFloat(35), y: CGFloat(0), width: CGFloat(cell.frame.width * 1/3), height: CGFloat(30))
                cell.contentView.addSubview(label)

                var textField = UITextField()

                textField.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(cell.frame.width * 2/3), height: CGFloat(30))

                textField.borderStyle = .roundedRect
                textField.backgroundColor = UIColor.magenta
                textField.text = "TEST TEST TEST"

                textField.textColor = UIColor.black
                textField.translatesAutoresizingMaskIntoConstraints = false

                cell.contentView.addSubview(textField)

Let me know if this works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM