Swift - constraints - dynamic label width - ios

I have three buttons in one "line".
A - B --- C
I have programatically added these constraints:
A has constraints:
leading to superview (value = 16)
width (value = 49)
height (value = 40)
trailing to B (value = 16)
top to top layout guide (value = 16)
B has constraints:
width (value = 49)
height (value = 40)
top to top layout guide (value = 16)
C has constraints:
trailing to superview (value = 16)
height (value = 40)
top to top layout guide (value = 16)
leading to B (value >= 20)
Now leading to B in C cause error if I run app and complains on "Unable to simultaneously satisfy constraints."
I thought that this is caused by "missing" content (it is added later in runtime) of C label and therefore unknown width.
I have tried manually to add for C:
width (value = 20)
The "error" still remains, but this should fulfill the condition for leading to B >= 20.
However, If I run app, even though the error is printed, the UI looks correct. What is the problem / solution for this?
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSAutoresizingMaskLayoutConstraint:0x1c4098ab0 h=--& v=--& UIView:topView.width == 0 (active)>",
"<NSLayoutConstraint:0x1c4092480 H:[UIView:parentParent]-(0)-| (active, names: '|':UIView:topView )>",
"<NSLayoutConstraint:0x1c40924d0 UIVIew:topView.leading == UIView:parentParent.leading (active)>",
"<NSLayoutConstraint:0x1c0094140 H:|-(0)-[UIView:parent](LTR) (active, names: '|':UIView:parentParent )>",
"<NSLayoutConstraint:0x1c00940a0 UIView:parent.right == UIView:parentParent.right (active)>",
"<NSLayoutConstraint:0x1c0094000 H:|-(16)-[UIButton:A] (active, names: '|':UIView:parent )>",
"<NSLayoutConstraint:0x1c0093f60 UIButton:A.trailing == UIButton:B.leading - 16 (active)>",
"<NSLayoutConstraint:0x1c0094730 H:[UIButton:B]-(>=20)-[UIButton:C] (active)>",
"<NSLayoutConstraint:0x1c0094780 UIButton:C.trailing == UIView:parent.trailing - 16 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x1c0094730 H:[UIButton:B]-(>=20)-[UIButton:C] (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
where A, B, C are presented Buttons, parent is their parent view. Entire parent view is inside parentParent and all is in top view.

Your view has autoresizing masks translated to constraints, try remove them:
button.translatesAutoresizingMaskIntoConstraints = false

I have tested your constraints but I don't see errors.
Unfortunately the console log at runtime is not fun to read, if you use a Xcode >= 7 you can set an identifier to your constraints, select it and go to the "Attributes inspector" like in this image:
After this, your log is more readable.
If you have problems, you can edit your post with the complete log of the error.
EDIT:
The problem would seem with the parent(s) view.
In this image you can see my test (without errors in the log), I've added only the height constraints to parent and parentParent, you can check the difference.

Related

Using UIScreen width property is breaking constraint of UITableViewCell

I am trying to constraint UITableViewCell programmatically. My cell consists of a simple pager. My init method of cell includes following.
height = UIScreen.main.bounds.width * 0.56 // If I use static i.e 320 value it is ok.
width = UIScreen.main.bounds.width is ok.
pagerView.topAnchor.constrain(to: topAnchor)
pagerView.bottomAnchor.constrain(to: bottomAnchor)
pagerView.widthAnchor.constrain(to: width)
pagerView.heightAnchor.constrain(to: height)
When I try to constraint using UIScreen.main.bounds.width it gives me following error. However, if I use static 320 value instead of UIScreen width it is all good.
> 2020-02-25 16:07:44.209043+0300 myApp[23049:780168]
> [LayoutConstraints] Unable to simultaneously satisfy constraints.
> Probably at least one of the constraints in the following list is one
> you don't want. Try this: (1) look at each constraint and try to
> figure out which you don't expect; (2) find the code that added the
> unwanted constraint or constraints and fix it. (
> "<NSLayoutConstraint:0x6000035345f0 V:|-(0)-[FSPagerView.FSPagerView:0x7fb96c6226f0] (active, names:
> '|':myApp.HomePagerCell:0x7fb96e041c00'HomePagerCell' )>",
> "<NSLayoutConstraint:0x6000035346e0 FSPagerView.FSPagerView:0x7fb96c6226f0.bottom ==
> myApp.HomePagerCell:0x7fb96e041c00'HomePagerCell'.bottom (active)>",
> "<NSLayoutConstraint:0x600003534780 FSPagerView.FSPagerView:0x7fb96c6226f0.height == 231.84 (active)>",
> "<NSLayoutConstraint:0x600003534aa0 'UIView-Encapsulated-Layout-Height'
> myApp.HomePagerCell:0x7fb96e041c00'HomePagerCell'.height == 232
> (active)>" ) Will attempt to recover by breaking constraint
> <NSLayoutConstraint:0x600003534780
> FSPagerView.FSPagerView:0x7fb96c6226f0.height == 231.84 (active)>
> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints
> to catch this in the debugger. The methods in the
> UIConstraintBasedLayoutDebugging category on UIView listed in
> <UIKitCore/UIView.h> may also be helpful.
What could be the reason of it and how can I solve it?

Autolayout warning when using prompt in navigation bar

I am using a navigation bar with a prompt, looking like this:
I receive the following auto layout warnings in the console:
2019-09-01 21:26:03.225576+0200 Hortus[85622:2386450] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX (active)>",
"<NSLayoutConstraint:0x600002d15c20 UILabel:0x7fc9eb816f50'Testen'.leading >= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.leading (active)>",
"<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0 (active)>",
"<NSLayoutConstraint:0x600002d16a30 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600002d15c20 UILabel:0x7fc9eb816f50'Testen'.leading >= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.leading (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2019-09-01 21:26:03.226198+0200 Hortus[85622:2386450] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX (active)>",
"<NSLayoutConstraint:0x600002d15540 UILabel:0x7fc9eb816f50'Testen'.trailing <= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.trailing (active)>",
"<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0 (active)>",
"<NSLayoutConstraint:0x600002d14320 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide']-(8)-|(LTR) (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"
"<NSAutoresizingMaskLayoutConstraint:0x60000043be30 h=--& v=--& _UINavigationBarModernPromptView:0x7fb3c6416640.width == 0 (active)>",
"<NSLayoutConstraint:0x600000421400 UILabel:0x7fb3c66d8bf0'Plant guide'.centerX == _UINavigationBarModernPromptView:0x7fb3c6416640.centerX (active)>",
"<NSLayoutConstraint:0x600000421f90 UILabel:0x7fb3c66d8bf0'Plant guide'.trailing <= UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide'.trailing (active)>",
"<NSLayoutConstraint:0x600000421e00 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide']-(20)-|(LTR) (active, names: '|':_UINavigationBarModernPromptView:0x7fb3c6416640 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600002d15540 UILabel:0x7fc9eb816f50'Testen'.trailing <= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.trailing (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
These warnings are given for the prompt in the navigation bar, but I do not set the autolayout constraints for the navigation bar. This should be handled by IOS itself.
What can I do to fix these warnings?
[Edit] The warnings are given in prepare() when segueing to the view controller. I set the prompt in prepare(). The segue is to a storyboard reference and is defined as 'present modally'. The storyboard reference references a UINavigationController. The prompt is set on the root view controller of the navigation controller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier {
switch identifier {
case "editImage":
let nc = segue.destination as? TTImageNavigationController
if let rvc = nc?.rootViewController as? TTImageEditorController {
rvc.navigationItem.prompt = navigationItem.prompt
}
default:
break
}
}
}
[EDIT] It seems that the problem is not clear to most of the people who react. Again... I do not set any auto layout settings in code or storyboard. The problem occurs in the navigation bar after setting the prompt in the prepare() function prior to the segue. The code is given above. Any reactions that say that I have to change or check my constraints are not helpful, because there are no constraints to check!
[EDIT] As requested by Mohsen, I created a small sample project on github: https://bitbucket.org/Leontien/navigationbarautolayoutwarning/src/master/
It’s not your bug. It’s Apple’s bug. Ignore the console. File a report with Apple and move on.
Set priority to your constraints. This will fulfill constraints according to priority. Please refer this link.
you set centerX for the label and set leading and trailing for right and left buttons, also you didn't set any width constraint for UILabel
"<NSLayoutConstraint:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX (active)>",
"<NSLayoutConstraint:0x600002d15c20 UILabel:0x7fc9eb816f50'Testen'.leading >= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.leading (active)>",
"<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0 (active)>",
"<NSLayoutConstraint:0x600002d16a30 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"
.
"<NSLayoutConstraint:0x600002d16990 UILabel:0x7fc9eb816f50'Testen'.centerX == _UINavigationBarModernPromptView:0x7fc9ebe27780.centerX (active)>",
"<NSLayoutConstraint:0x600002d15540 UILabel:0x7fc9eb816f50'Testen'.trailing <= UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide'.trailing (active)>",
"<NSLayoutConstraint:0x600002d10ff0 '_UITemporaryLayoutWidth' _UINavigationBarModernPromptView:0x7fc9ebe27780.width == 0 (active)>",
"<NSLayoutConstraint:0x600002d14320 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000037571e0'UIViewLayoutMarginsGuide']-(8)-|(LTR) (active, names: '|':_UINavigationBarModernPromptView:0x7fc9ebe27780 )>"
"<NSAutoresizingMaskLayoutConstraint:0x60000043be30 h=--& v=--& _UINavigationBarModernPromptView:0x7fb3c6416640.width == 0 (active)>",
"<NSLayoutConstraint:0x600000421400 UILabel:0x7fb3c66d8bf0'Plant guide'.centerX == _UINavigationBarModernPromptView:0x7fb3c6416640.centerX (active)>",
"<NSLayoutConstraint:0x600000421f90 UILabel:0x7fb3c66d8bf0'Plant guide'.trailing <= UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide'.trailing (active)>",
"<NSLayoutConstraint:0x600000421e00 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600001e58fc0'UIViewLayoutMarginsGuide']-(20)-|(LTR) (active, names: '|':_UINavigationBarModernPromptView:0x7fb3c6416640 )>"
for solve this warning you should remove leading and trailing constraint from UILabel and set left button with leading to superview and right button's trailing to superview as well.
or you can use a navigation bar object, it has a label and also you can add barButtonItem to it.
you can add width constraint for the UILabel but it will be conflict on another devices when you run it on some other devices
This helps to debug broken constraint issue by providing a more readable output
Create an extension for NSLayoutConstraint
extension NSLayoutConstraint {
override open var description: String {
let id = identifier ?? ""
return "Constraint ID: \(id), constant: \(constant)"
}
}
set a unique identifier for every constraint in the storyboard
you'll get a more readable output pointing out which constraint id is broken
change the priority for broken constraint

Scrollview working by breaking constraint

I have a UIViewController containing a scrollView: the scrollView is pinned (0,0,0,0) to the superview.
The scrollView contains a Content View with the following constraints set:
Inside this view, I put a square image view: it is pinned this way and its height equals the width of its superview.
Anything I described until now is done manually in the storyboard.
Then, using a simple button (so, after viewDidLoad, viewDidLayoutSubviews, etc.), I execute the following function (that 375 is currently hard-coded, but it is the heigth of the image view frame on the device I’m using for testing purposes):
var startH = 0
for i in 0...10 {
let v = UIView(frame: CGRect(x: 0, y: 375+startH, width: 375, height: startH))
v.backgroundColor = .random
contentView.addSubview(v)
startH += 100
}
let scrollerLayoutGuide = scrollView.contentLayoutGuide
scrollerLayoutGuide.heightAnchor.constraint(equalToConstant: CGFloat(startH+375)).isActive = true
scrollView.contentSize = contentView.frame.size
This should (and actually it does) create 11 views under the imageView, inside the contentView of the scrollView.
Problem is when I execute this function I get the following error:
[LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (
"<NSLayoutConstraint:0x6000019d7d40 UIView:0x7fe66940aa30.height == UIScrollView:0x7fe66985b400.height (active)>",
"<NSLayoutConstraint:0x6000019d7d90 V:|-(0)-[UIView:0x7fe66940aa30] (active, names: '|':UIScrollView:0x7fe66985b400 )>",
"<NSLayoutConstraint:0x6000019d7de0 V:[UIView:0x7fe66940aa30]-(0)-| (active, names: '|':UIScrollView:0x7fe66985b400 )>",
"<NSLayoutConstraint:0x6000019e4690 UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide'.bottom == UIScrollView:0x7fe66985b400.bottom (active)>",
"<NSLayoutConstraint:0x6000019e4730 UIScrollView:0x7fe66985b400.top == UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide'.top (active)>",
"<NSLayoutConstraint:0x6000019e11d0 _UIScrollViewLayoutGuide:0x6000003ac1c0'UIScrollView-contentLayoutGuide'.height
== 1475 (active)>",
"<NSLayoutConstraint:0x6000019e9540 'UIView-Encapsulated-Layout-Height' UIView:0x7fe66950bdb0.height == 667 (active)>",
"<NSLayoutConstraint:0x6000019e45f0 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide']-(0)-| (active, names: '|':UIView:0x7fe66950bdb0 )>",
"<NSLayoutConstraint:0x6000019e4550 'UIViewSafeAreaLayoutGuide-top' V:|-(20)-[UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide'] (active, names: '|':UIView:0x7fe66950bdb0 )>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x6000019d7de0 V:[UIView:0x7fe66940aa30]-(0)-| (active, names: '|':UIScrollView:0x7fe66985b400 )>
Problem is I can't understand what constraint is causing this issue and, most of all, why. Could you help me?
There is conflict between your constraints with contentView
1. There is Top, bottom, leading, trailing with the scrollview
2. Fixed height and fixed width constraint of contentView
These two will conflict each other as OS will not be sure which constraint to fulfil.
As a solution reduce the priority of height and width constraint so that the more priority is given to the constraint with respect to the scrollView.
For more details please follow below tutorial
How to configure a UIScrollView with Auto Layout

Unable to simultaneously satisfy constraints when update height constraints of imageView swift 4

I have a stack view that look like the figure below:
So I change the height of the image programmatically to make it fit the image that download from my server,if dont have image,the height constraints of image will set to be zero.
Here is my code to doing so:
let imageUrl = URL(string :imageString)
if let data = try? Data(contentsOf: imageUrl!)
{
guard let actualImage: UIImage = UIImage(data: data) else{
print("No image!")
ImageView.image = nil
defaultImageHeightContrainst = ImageHeightContrainst.constant
ImageHeightContrainst.constant = 0
layoutIfNeeded()
return
}
let imageHeight = actualImage.size.height * actualImage.scale
print("imageHeight = \(imageHeight)")
defaultImageHeightContrainst = ImageHeightContrainst.constant
ImageHeightContrainst.constant = imageHeight
layoutIfNeeded()
//here display the image to the imageview
ImageView.kf.setImage(with: imageUrl)
}
With the code above,the image height is scale according to actual image height which download from internet.If dont have image,the "image" part also set to 0 already.
This is what I expected,but now I face an error below whenever the "image" height become taller in order to fit the actual image height
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x6080002868b0 UIImageView:0x7f9cbae59240.height == 50 (active)>",
"<NSLayoutConstraint:0x608000286bd0 UIView:0x7f9cbae5ad80.height == 1 (active)>",
"<NSLayoutConstraint:0x608000286d10 UIImageView:0x7f9cbae5b440.height == 458 (active)>",
"<NSLayoutConstraint:0x608000286f90 UIView:0x7f9cbae5bb50.height == 1 (active)>",
"<NSLayoutConstraint:0x6080002871c0 V:|-(0)-[UILabel:0x7f9cbae5b160] (active, names: '|':UIStackView:0x7f9cbae5af60 )>",
"<NSLayoutConstraint:0x608000287350 V:[UILabel:0x7f9cbae5b160]-(10)-[UIImageView:0x7f9cbae5b440] (active)>",
"<NSLayoutConstraint:0x6080002873a0 V:[UIImageView:0x7f9cbae5b440]-(10)-[UIStackView:0x7f9cbae5b670] (active)>",
"<NSLayoutConstraint:0x608000287580 V:[UIStackView:0x7f9cbae5b670]-(10)-[UIView:0x7f9cbae5bb50] (active)>",
"<NSLayoutConstraint:0x6080002875d0 V:[UIStackView:0x7f9cbae5c0f0]-(0)-| (active, names: '|':UIStackView:0x7f9cbae5af60 )>",
"<NSLayoutConstraint:0x608000287670 V:[UIView:0x7f9cbae5bb50]-(10)-[UIStackView:0x7f9cbae5c0f0] (active)>",
"<NSLayoutConstraint:0x6080002877b0 V:|-(10)-[UIImageView:0x7f9cbae59240] (active, names: '|':UITableViewCellContentView:0x7f9cbae5a0c0 )>",
"<NSLayoutConstraint:0x6080002878f0 V:[UIImageView:0x7f9cbae59240]-(8)-[UIView:0x7f9cbae5ad80] (active)>",
"<NSLayoutConstraint:0x6080002879e0 V:[UIStackView:0x7f9cbae5af60]-(10)-| (active, names: '|':UITableViewCellContentView:0x7f9cbae5a0c0 )>",
"<NSLayoutConstraint:0x608000287a80 V:[UIView:0x7f9cbae5ad80]-(8)-[UIStackView:0x7f9cbae5af60] (active)>",
"<NSLayoutConstraint:0x608000288c00 'UISV-canvas-connection' UIStackView:0x7f9cbae5c0f0.top == _UILayoutSpacer:0x6080001cd5c0'UISV-alignment-spanner'.top (active)>",
"<NSLayoutConstraint:0x608000288ca0 'UISV-canvas-connection' V:[_UILayoutSpacer:0x6080001cd5c0'UISV-alignment-spanner']-(0)-| (active, names: '|':UIStackView:0x7f9cbae5c0f0 )>",
"<NSLayoutConstraint:0x608000289970 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f9cbae5a0c0.height == 476.5 (active)>"
)
Before asking,I already checked all my other constraints,which is all set correctly.I even disable all the code that can change the height of "image",once disable,there is no problem.The error only occurred when I intend to change the height.
I even tried to add ImageView.translatesAutoresizingMaskIntoConstraints = false before layoutIfNeeded(),but the error is still exist.
So what is the correct way to change the height of image in order to fit the actual image download from server?
Considering that the last constraint says
"<NSLayoutConstraint:0x608000289970 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f9cbae5a0c0.height == 476.5 (active)>"
I assume you are using stackView inside of a UITableViewCell to implement automatic height cells in a tableView. If my assumption is correct, then the problem is not with the stackView, nor with the imageView, but with the way UITableView works with UITableViewAutomaticDimension and Autolayout. If the layout works as you expect, and the warning is the only thing that bugs you, then read following.
Therefore it seems to me that this is a result of an known "bug" - there is a collision of the height set by the tableView and the height calculated by the autolayout. When rendering the cell, the tableView first applies the default height, calculates the autolayout height, and then use the latter - at least it seems so. See my question. The constraint mentioned above ('UIView-Encapsulated-Layout-Height') is the one applied by the UITableView that later goes away.
That means that the constraints you are using are probably OK. Just set one of the constraints defining height to priority = 999 (so that until it deactivates the default height constraint it won't cause any conflict). In the end, it will result in using your constraint anyway, so it will not cause any layout trouble.
E.g., if you constrain the stackView to fit the cell's contentView, set the stackView.bottomAnchor to contentView.bottomAnchor just with the priority set to 999. If you did the layout programmatically, this might be your solution:
let bottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
bottomConstraint.priority = UILayoutPriority(rawValue: 999)
NSLayoutConstraint.activate([
// rest of the constraints
stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
stackView.leftAnchor.constraint(equalTo: contentView.leftAnchor),
stackView.rightAnchor.constraint(equalTo: contentView.rightAnchor),
bottomConstraint,
])
If you do the layout in storyboards, just select appropriate constraint in the storyboards, and in the attributes inspector set its priority to 999 (for example):

autolayout constraints not working correctly when adding them programmatically

this is my view
the black area is a view, called containerView that has the following constrains
i want to add a uitableView to it dyrnamically, i did this:
func setConstraintsForTableView(tableView: UITableView){
self.containerView.addSubview(tableView)
let bottomConstraint = tableView.bottomAnchor.constraintEqualToAnchor(self.containerView.bottomAnchor)
let leftConstraint = tableView.leftAnchor.constraintEqualToAnchor(self.containerView.leftAnchor)
let rightConstraint = tableView.rightAnchor.constraintEqualToAnchor(self.containerView.rightAnchor)
let topConstraint = tableView.topAnchor.constraintEqualToAnchor(self.containerView.topAnchor)
self.containerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activateConstraints([bottomConstraint, leftConstraint, rightConstraint, topConstraint])
self.containerView.layoutIfNeeded()
}
but i got this in the log:
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSAutoresizingMaskLayoutConstraint:0x7fe8c9c2ddb0 h=--& v=--& UITableView:0x7fe8cd05c200.midX == + 120>",
"<NSLayoutConstraint:0x7fe8c9e97340 UIView:0x7fe8c9e8aeb0.trailingMargin == UIView:0x7fe8cb304490.trailing>",
"<NSLayoutConstraint:0x7fe8c9e97390 UIView:0x7fe8cb304490.leading == UIView:0x7fe8c9e8aeb0.leadingMargin>",
"<NSLayoutConstraint:0x7fe8c9c2cf70 H:|-(0)-[UITableView:0x7fe8cd05c200](LTR) (Names: '|':UIView:0x7fe8cb304490 )>",
"<NSLayoutConstraint:0x7fe8c9c2d0c0 UITableView:0x7fe8cd05c200.right == UIView:0x7fe8cb304490.right>",
"<NSLayoutConstraint:0x7fe8cb104c40 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7fe8c9e8aeb0(375)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fe8c9c2d0c0 UITableView:0x7fe8cd05c200.right == UIView:0x7fe8cb304490.right>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2015-12-19 22:12:16.201 GrabATable[2419:218311] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<_UILayoutSupportConstraint:0x7fe8cb036c70 V:[_UILayoutGuide:0x7fe8c9e956a0(20)]>",
"<_UILayoutSupportConstraint:0x7fe8cb0365c0 V:|-(0)-[_UILayoutGuide:0x7fe8c9e956a0] (Names: '|':UIView:0x7fe8c9e8aeb0 )>",
"<_UILayoutSupportConstraint:0x7fe8cb0363d0 V:[_UILayoutGuide:0x7fe8c9e96410(0)]>",
"<_UILayoutSupportConstraint:0x7fe8cb018490 _UILayoutGuide:0x7fe8c9e96410.bottom == UIView:0x7fe8c9e8aeb0.bottom>",
"<NSAutoresizingMaskLayoutConstraint:0x7fe8c9c2de50 h=--& v=--& UITableView:0x7fe8cd05c200.midY == + 64>",
"<NSLayoutConstraint:0x7fe8c9e97070 UIImageView:0x7fe8c9e8a160.height == 0.33*UIView:0x7fe8c9e8aeb0.height>",
"<NSLayoutConstraint:0x7fe8c9e97110 V:[_UILayoutGuide:0x7fe8c9e956a0]-(0)-[UIImageView:0x7fe8c9e8a160]>",
"<NSLayoutConstraint:0x7fe8c9e972f0 V:[UIImageView:0x7fe8c9e8a160]-(20)-[UIView:0x7fe8cb304490]>",
"<NSLayoutConstraint:0x7fe8c9e973e0 V:[UIView:0x7fe8cb304490]-(0)-[_UILayoutGuide:0x7fe8c9e96410]>",
"<NSLayoutConstraint:0x7fe8c9c2cc50 UITableView:0x7fe8cd05c200.bottom == UIView:0x7fe8cb304490.bottom>",
"<NSLayoutConstraint:0x7fe8c9c2d210 V:|-(0)-[UITableView:0x7fe8cd05c200] (Names: '|':UIView:0x7fe8cb304490 )>",
"<NSLayoutConstraint:0x7fe8cb104c90 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fe8c9e8aeb0(667)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fe8c9c2cc50 UITableView:0x7fe8cd05c200.bottom == UIView:0x7fe8cb304490.bottom>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Output of interest:
"<NSAutoresizingMaskLayoutConstraint:0x7fe8c9c2ddb0 h=--& v=--& UITableView:0x7fe8cd05c200.midX == + 120>",
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fe8c9c2d0c0 UITableView:0x7fe8cd05c200.right == UIView:0x7fe8cb304490.right>
You need to set translatesAutoresizingMaskIntoConstraints to false on the tableView. See the UIView class Reference for more detail.
tableView.translatesAutoresizingMaskIntoConstraints = false
From the UIView Class Reference:
Discussion
If this property’s value is true, the system creates a set
of constraints that duplicate the behavior specified by the view’s
autoresizing mask. This also lets you modify the view’s size and
location using the view’s frame, bounds, or center properties,
allowing you to create a static, frame-based layout within Auto
Layout.
Note that the autoresizing mask constraints fully specify the view’s
size and position; therefore, you cannot add additional constraints to
modify this size or position without introducing conflicts. If you
want to use Auto Layout to dynamically calculate the size and position
of your view, you must set this property to false, and then provide a
non ambiguous, nonconflicting set of constraints for the view.
By default, the property is set to true for any view you
programmatically create. If you add views in Interface Builder, the
system automatically sets this property to false.

Resources