Giter Club home page Giter Club logo

Comments (3)

robb avatar robb commented on May 28, 2024

First of all, thanks for providing a way to recreate that issue 💖

There are some subtleties to this, let me try to address them one by one:

Order off adding the constraints appears to matter. If view A is put inside view B, then if view B has it's constraints added before A's then the phantom constraint isn't added. In practice this workaround is pretty clunky.

I've been able to confirm this. if contentView does not have a superview of its own when it is being layouted, that extra NSLayoutConstraint is added, even if translatesAutoresizingMaskIntoConstraints is explicitly set to false.

However, I'm not sure that I agree that setting up the view hierarchy before adding constraints is clunky, considering that NSLayoutConstraints may leak outside a sub-tree and affect the entire window. I'd probably suggest the opposite, trying to always set up the view hierarchy before adding constraints where possible. Ultimately, it's your decision though.

Adding the same constraints using the NSLayoutConstraint methods doesn't exhibit this behavior.

This is true, but the two code snippets in your example are not 100% equivalent.

This

layout(label) { label in
    label.left == label.superview!.left

    label.right == label.superview!.right - 10

    label.top == label.superview!.top
    label.bottom == label.superview!.bottom
}

will call layoutIfNeeded on label.superview once the constraints are installed. That call, since label.superview does not yet have a superview of its own, will install that phantom constraint as outlined above.

On the other hand, your alternative solution

self.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .Left, relatedBy: .Equal, toItem: self.contentView, attribute: .Left, multiplier: 1, constant: 0))
self.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .Right, relatedBy: .Equal, toItem: self.contentView, attribute: .Right, multiplier: 1, constant: -10))
self.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .Top, relatedBy: .Equal, toItem: self.contentView, attribute: .Top, multiplier: 1, constant: 0))
self.contentView.addConstraint(NSLayoutConstraint(item: label, attribute: .Bottom, relatedBy: .Equal, toItem: self.contentView, attribute: .Bottom, multiplier: 1, constant: 0))

will only set up the constraints. Since that code is almost immediately followed by self.view.addSubviews([contentView]), layouting will occur after contentView has been added to view, not resulting in a phantom constraint.

If you'd like to set up the constraints before adding the subviews, you would need to defer the layout pass. You can do this by using Cartography's constrain function like so:

constrain(label) { label in
    label.left == label.superview!.left

    label.right == label.superview!.right - 10

    label.top == label.superview!.top
    label.bottom == label.superview!.bottom
}

That seems to work fine in the example project you provided 👌

from cartography.

brandonroth avatar brandonroth commented on May 28, 2024

Using constrain works in my situation and eliminates the problem. Thanks for cluing me into the constrain method.

think the phantom constrain thing is either a bug / feature / something else in the layout engine itself because I experienced it again when working with a dynamically sized tableview header. My problem there is that I had called layoutIfNeeded on my header before adding it to the tableview and I was seeing the same phantom constraint.

from cartography.

robb avatar robb commented on May 28, 2024

Closing this one then, feel free to reopen it if you have any more questions.

from cartography.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.