Comments (3)
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.
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.
Closing this one then, feel free to reopen it if you have any more questions.
from cartography.
Related Issues (20)
- Create new release to include recent updates HOT 1
- How do I have the status bar visible and yet have the topView functional? HOT 2
- Invalid redeclaration of '~', Xcode 9.4.1, swift 4.1, pod 'Cartography' HOT 3
- NSLayoutConstraints.Attribute & .Relation HOT 1
- Universal way of defining SafeArea constraints HOT 5
- Issues building the latest version HOT 3
- no is ios
- Publish v3.1.0 to Cocoapods? HOT 1
- Swift5 HOT 1
- Xcode 11 beta build error HOT 4
- Mac Catalyst issues HOT 3
- xcode11,swift 4 ---Header 'Cartography-Swift.h' not found HOT 1
- How to use multiply
- Xcode12.1 deprecated warning
- Cartography is still awesome 2021-01
- Question: Is this project still active? HOT 2
- Build is not working
- speed of == operator overload HOT 1
- Namespace collision with SwiftUI 'View' HOT 1
- target '<Your Target Name>' do pod 'Cartography', '~> 3.0' end HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cartography.