Search code examples
iosswiftconstraintsxcode6.1

Formatting TextViews through constraints using visual format in Swift


I tried using the visual format to add constraints to two TextViews like this:

func addElements() {
    var questionText = UITextView(frame: CGRect())
    questionText.backgroundColor = UIColor.orangeColor()
    questionText.text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam "
    questionText.editable = false
    self.view.addSubview(questionText)
    questionText.setTranslatesAutoresizingMaskIntoConstraints(false)

    var aText = UITextView(frame: CGRect())
    aText.backgroundColor = UIColor.purpleColor()
    aText.text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam "
    aText.editable = false
    self.view.addSubview(aText)
    questionText.setTranslatesAutoresizingMaskIntoConstraints(false)

    var viewDict = Dictionary<String, UIView>()
    viewDict["questionText"] = questionText
    viewDict["aText1"] = aText
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[questionText]-|", options: nil, metrics: nil, views: viewDict))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[aText1]-|", options: nil, metrics: nil, views: viewDict))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[questionText]-[aText1]-|", options: nil, metrics: nil, views: viewDict))

But when I compile this code the iPhone screens remains blank. I was able to display "questionText" by adding a height and a width value, but this did not work for aText1. Shoudln't Swift be able to determine the correct height and width, e.g. when I'm writing "|-[elem]-|" it automatically assumes "elem" has max size? Or is there something I'm missing? This is a snippet of the console output created by navigating to the main screen:

"<NSLayoutConstraint:0x7ff3e3f242f0 UITextView:0x7ff3e4885c00'Lorem ipsum dolor...'.leading == UIView:0x7ff3e3e422f0.leadingMargin>",
"<NSLayoutConstraint:0x7ff3e3f24370 UIView:0x7ff3e3e422f0.trailingMargin == UITextView:0x7ff3e4885c00'Lorem ipsum dolor...'.trailing>",

However, adding multiple elements like in the following example was no problem at all:

func addElements() {
    var questionText = UITextView(frame: CGRect())
    questionText.backgroundColor = UIColor.orangeColor()
    questionText.text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam"
    questionText.editable = false
    self.view.addSubview(questionText)
    questionText.setTranslatesAutoresizingMaskIntoConstraints(false)

    var checkBox1 = CheckBox(frame: CGRect(), selected: false)
    checkBox1.mDelegate = self
    checkBox1.tag = 1337
    self.view.addSubview(checkBox1)
    checkBox1.setTranslatesAutoresizingMaskIntoConstraints(false)

    var checkBox2 = CheckBox(frame: CGRect(), selected: false)
    checkBox2.mDelegate = self
    checkBox2.tag = 1337
    self.view.addSubview(checkBox2)
    checkBox2.setTranslatesAutoresizingMaskIntoConstraints(false)

    var viewDict = Dictionary<String, UIView>()
    viewDict["questionText"] = questionText
    viewDict["check1"] = checkBox1
    viewDict["check2"] = checkBox2
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[questionText]-|", options: nil, metrics: nil, views: viewDict))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[check1]-[check2]", options: nil, metrics: nil, views: viewDict))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[questionText]-[check1]-|", options: nil, metrics: nil, views: viewDict))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[questionText]-[check2]-|", options: nil, metrics: nil, views: viewDict))

The CheckBox is a subclass of UIButton.

In the end I'd lie to be able to create a View with a TextView at the top and multiple Checkboxes and Textviews on the same line, underneath it.


Solution

  • One problem is that it looks like you have a cut and paste error -- you have questionText.setTranslatesAutoresizingMaskIntoConstraints(false) where you should have aText.setTranslatesAutoresizingMaskIntoConstraints(false). If you fix that, you should see one of your two text views, but...

    the vfl string for the vertical constraints doesn't tell the system what the relative sizes of the two text views should be,

    "V:|-[questionText]-[aText1]-|"
    

    Try this, which should make both text views the same size,

    "V:|-[questionText]-[aText1(==questionText)]-|"
    

    or something like this, to give one of them a height,

    "V:|-[questionText(==200)]-[aText1]-|"
    

    Your second set of constraints, with the check boxes, worked because buttons have an intrinsic content size, while text views (and plain UIViews) don't. In that case, the buttons take up whatever their intrinsic size says they should, and the text view takes up the rest of the space (minus the padding).