CWineland
CWineland

Reputation: 615

Using auto layout in UITableviewCell

I am trying to use auto sizing UITableView cells in swift with snapKit! relevant flags set on the UITableView are as follows:

self.rowHeight = UITableViewAutomaticDimension
self.estimatedRowHeight = 70.0

I have a UITextField defined in my customUITableviewCell class like:

var uidTextField: UITextField = UITextField()

and the initial setup of the text field in my custom UITableViewCell looks like this:

self.contentView.addSubview(uidTextField)
uidTextField.attributedPlaceholder = NSAttributedString(string: "Woo Hoo", attributes: [NSForegroundColorAttributeName:UIColor.lightGrayColor()])
uidTextField.textAlignment = NSTextAlignment.Left
uidTextField.font = UIFont.systemFontOfSize(19)
uidTextField.returnKeyType = UIReturnKeyType.Done
uidTextField.autocorrectionType = UITextAutocorrectionType.No
uidTextField.delegate = self
uidTextField.addTarget(self, action: "uidFieldChanged", forControlEvents: UIControlEvents.EditingChanged)
uidTextField.snp_makeConstraints { make in 
    make.left.equalTo(self.contentView).offset(10)
    make.right.equalTo(self.contentView)
    make.top.equalTo(self.contentView).offset(10)
    make.bottom.equalTo(self.contentView).offset(10)
}

when I run the code it shows up cut off and gives me an error in the console that reads:

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

Is there something wrong with my autoLayout constraints or is this an issue with UIControls and autosizing of UITableView cells?

Upvotes: 4

Views: 3610

Answers (1)

joern
joern

Reputation: 27620

In SnapKit (and Masonry) you have to use negative values to add a padding to the right or bottom of a view. You are using offset(10) on your bottom constraint which causes the effect that the bottom 10pt of your text field will get cut off.

To fix this you have to give your bottom constraint a negative offset:

uidTextField.snp_makeConstraints { make in 
    make.left.equalTo(self.contentView).offset(10)
    make.right.equalTo(self.contentView)
    make.top.equalTo(self.contentView).offset(10)
    make.bottom.equalTo(self.contentView).offset(-10)
}

Or you could get the same constraints by doing this:

uidTextField.snp_makeConstraints { make in 
    make.edges.equalTo(contentView).inset(UIEdgeInsetsMake(10, 10, 10, 0))
}

When you are using the inset() way you have to use positive values for right and bottom inset.

I don't understand why SnapKit uses negative values for bottom and right. I think that's counterintuitive and a bit confusing.

EDIT: This is a little example that is working fine (I hardcoded a tableView with 3 custom cells that include a UITextField):

ViewController:

import UIKit
import SnapKit

class ViewController: UIViewController {
    let tableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(tableView)
        tableView.dataSource = self
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 70
        tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "CustomCell")

        tableView.snp_makeConstraints { (make) -> Void in
            make.edges.equalTo(view)
        }
    }
}

extension ViewController: UITableViewDataSource {
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

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

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

CustomTableViewCell:

import UIKit

class CustomTableViewCell: UITableViewCell {
    let textField = UITextField()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        textField.attributedPlaceholder = NSAttributedString(string: "Woo Hoo", attributes: [NSForegroundColorAttributeName:UIColor.lightGrayColor()])
        textField.textAlignment = NSTextAlignment.Left
        textField.font = UIFont.systemFontOfSize(19)
        textField.returnKeyType = UIReturnKeyType.Done
        textField.autocorrectionType = UITextAutocorrectionType.No
        contentView.addSubview(textField)

        textField.snp_makeConstraints { (make) -> Void in
            make.edges.equalTo(contentView).inset(UIEdgeInsetsMake(10, 10, 10, 0))
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Upvotes: 2

Related Questions