I'm loading a view controller which has a view that can take different size. The size is set in the "viewDidLayoutSubviews" and may differ regarding the parameter sent to the view.
I'm using auto-layout in my view, it consists of 2 labels under each other (title + error), a tableview, and two button side by side (confirm + cancel).
The view loads perfectly, but I still have this message:
* Xcode yelling about constraints then specify which one seem to be the problem *
(
"<_UILayoutSupportConstraint:0x604000281040 _UILayoutGuide:0x7f84ce652de0.height == 0 (active)>",
"<_UILayoutSupportConstraint:0x604000289830 _UILayoutGuide:0x7f84ce652de0.bottom == UIView:0x7f84ce66fea0.bottom (active)>",
"<NSLayoutConstraint:0x60000048b630 UIButton:0x7f84ce4b3c60'Continuer'.height == 60 (active)>",
"<NSLayoutConstraint:0x6040002963a0 UILabel:0x7f84ce670bd0'Sexe'.top == UILayoutGuide:0x6040001b2520'UIViewSafeAreaLayoutGuide'.top + 5 (active)>",
"<NSLayoutConstraint:0x6040002967b0 V:[UILabel:0x7f84ce670bd0'Sexe']-(0)-[UILabel:0x7f84ce43a770'Error'] (active)>",
"<NSLayoutConstraint:0x60400028c4e0 V:[UILabel:0x7f84ce43a770'Error']-(5)-[UITableView:0x7f84ce850000] (active)>",
"<NSLayoutConstraint:0x60400028c3a0 V:[UITableView:0x7f84ce850000]-(0)-[UIButton:0x7f84ce4b3c60'Continuer'] (active)>",
"<NSLayoutConstraint:0x60400028f0a0 V:[UIButton:0x7f84ce4b3c60'Continuer']-(0)-[_UILayoutGuide:0x7f84ce652de0] (active)>",
"<NSLayoutConstraint:0x60000048cda0 'UIView-Encapsulated-Layout-Height' UIView:0x7f84ce66fea0.height == 0 (active)>",
"<NSLayoutConstraint:0x604000296670 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x6040001b2520'UIViewSafeAreaLayoutGuide'] (active, names: '|':UIView:0x7f84ce66fea0 )>"
)
Any idea what constraint is causing me such troubles ?
(I could post the full Xcode message is its of any use, but I don't want to spam.)
My problem was that I was setting the height of the view after instantiating it, in the "viewDidLayoutSubviews".
I am using "Presentr" lib to instantiate a view easily.
My issue had nothing to do with constraints in the storyboard whatsoever.
I managed to fix the problem by specifying the height of my view BEFORE presenting with Presentr.
To do that, I did a protocol that forced my controller to have a "getHeight" func to get its height, allowing me to to something like that
let customType = PresentationType.custom(width: .custom(size: Float(self.view.frame.width)), height: .custom(size: editProfileVC.getHeight()), center: .center)
You can see here that, for the height, I'm using "editProfileVC.getHeight()"
I hope it can help others too.
Related
I've got a SwiftUI View containing a NavigationView and some NavigationLinks. For some reason I got a error message regarding LayoutConstraints. This error is also discussed in this SO Question, with recommended solution setting the navigationViewStyle by .navigationViewStyle(StackNavigationViewStyle()) or .navigationViewStyle(.stack).
However by setting the navigationViewStyle to StackNavigation, the Layout is modified in a non intended way. Using StackNavigation will change the Layout on both IOS and IPadOS to a simple List. Not configuring navigationViewStyle or setting it to .automatic will lead to having a List on IOS and a multiple columns on IPadOS.
Additionally the LayoutConstraints error seems to be a error only occur on IOS.
How can I get rid of the LayoutConstraints error (on IOS) without using StackNavigation? Is it possible to distinguish between IOS/IPadOS?
My View:
struct ProgramView: View {
#ObservedObject var itemViewModel: ItemViewModel
var body: some View {
NavigationView {
VStack {
ForEach(itemViewModel.filteredSessions, id: \.id) { session in
NavigationLink(
destination: SessionDetail(session: session)
) {
SessionRow(session: session)
}
}
// shortened for brevity
}
.navigationTitle("Program")
.navigationBarItems(trailing: UpdateApiButton(itemViewModel: itemViewModel))
}
.navigationViewStyle(.automatic) // default behaviour
.navigationViewStyle(.stack) // Stack; shows a List for IOS+IPadOS; IPadOS should remain multi-column
.navigationViewStyle(.columns) // Uses multi-column also in IOS
}
}
The LayoutConstraints error:
2022-04-06 20:43:49.474918+0200 XXX[1505:41050] [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:0x282b8b2f0 'BIB_Trailing_CB_Leading' H:[_UIModernBarButton:0x104c1f610]-(6)-[_UIModernBarButton:0x104c1d7e0'Program'] (active)>",
"<NSLayoutConstraint:0x282b8b340 'CB_Trailing_Trailing' _UIModernBarButton:0x104c1d7e0'Program'.trailing <= _UIButtonBarButton:0x104c1d400.trailing (active)>",
"<NSLayoutConstraint:0x282b813b0 'UINav_static_button_horiz_position' _UIModernBarButton:0x104c1f610.leading == UILayoutGuide:0x2831b9a40'UIViewLayoutMarginsGuide'.leading (active)>",
"<NSLayoutConstraint:0x282b8b7a0 'UINavItemContentGuide-leading' H:[_UIButtonBarButton:0x104c1d400]-(6)-[UILayoutGuide:0x2831b9960'UINavigationBarItemContentLayoutGuide'] (active)>",
"<NSLayoutConstraint:0x282b89680 'UINavItemContentGuide-trailing' UILayoutGuide:0x2831b9960'UINavigationBarItemContentLayoutGuide'.trailing == _UINavigationBarContentView:0x104c1c430.trailing (active)>",
"<NSLayoutConstraint:0x282bfce60 'UIView-Encapsulated-Layout-Width' _UINavigationBarContentView:0x104c1c430.width == 0 (active)>",
"<NSLayoutConstraint:0x282b89a40 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x2831b9a40'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UINavigationBarContentView:0x104c1c430 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x282b8b2f0 'BIB_Trailing_CB_Leading' H:[_UIModernBarButton:0x104c1f610]-(6)-[_UIModernBarButton:0x104c1d7e0'Program'] (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.
2022-04-06 20:43:49.476126+0200 XXX[1505:41050] [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:0x282b8a760 UIView:0x104c20b90.trailing == _UIBackButtonMaskView:0x104c1afe0.trailing (active)>",
"<NSLayoutConstraint:0x282b80eb0 'Mask_Trailing_Trailing' _UIBackButtonMaskView:0x104c1afe0.trailing == _UIButtonBarButton:0x104c1d400.trailing (active)>",
"<NSLayoutConstraint:0x282b80ff0 'MaskEV_Leading_BIB_Trailing' H:[_UIModernBarButton:0x104c1f610]-(0)-[UIView:0x104c20b90] (active)>",
"<NSLayoutConstraint:0x282b813b0 'UINav_static_button_horiz_position' _UIModernBarButton:0x104c1f610.leading == UILayoutGuide:0x2831b9a40'UIViewLayoutMarginsGuide'.leading (active)>",
"<NSLayoutConstraint:0x282b8b7a0 'UINavItemContentGuide-leading' H:[_UIButtonBarButton:0x104c1d400]-(6)-[UILayoutGuide:0x2831b9960'UINavigationBarItemContentLayoutGuide'] (active)>",
"<NSLayoutConstraint:0x282b89680 'UINavItemContentGuide-trailing' UILayoutGuide:0x2831b9960'UINavigationBarItemContentLayoutGuide'.trailing == _UINavigationBarContentView:0x104c1c430.trailing (active)>",
"<NSLayoutConstraint:0x282bfce60 'UIView-Encapsulated-Layout-Width' _UINavigationBarContentView:0x104c1c430.width == 0 (active)>",
"<NSLayoutConstraint:0x282b89a40 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x2831b9a40'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':_UINavigationBarContentView:0x104c1c430 )>"
)
Thanks in advance!
I currently have a UITableView embedded inside a UIStackView. I've currently set the StackView to have its own padding like so:
stackView.layoutMargins = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
stackView.isLayoutMarginsRelativeArrangement = true
I've also set the stackview to be set on its edges, and it's also under a scrollview.
However, applying those settings, I'm getting errors on the UITableView constraints, telling me that the layout margins constraints are the issue.
(
"<NSLayoutConstraint:0x600000645f90 UIStackView:0x7fa9bbc32260.width == UIScrollView:0x7fa9bc019800.width (active)>",
"<NSLayoutConstraint:0x6000006441e0 H:|-(0)-[UIScrollView:0x7fa9bc019800](LTR) (active, names: '|':COVID_19_Compliance_Coach.DashboardView:0x7fa9bbc11340 )>",
"<NSLayoutConstraint:0x600000644320 UIScrollView:0x7fa9bc019800.right == COVID_19_Compliance_Coach.DashboardView:0x7fa9bbc11340.right (active)>",
"<NSLayoutConstraint:0x600000646f30 '_UITemporaryLayoutWidth' COVID_19_Compliance_Coach.DashboardView:0x7fa9bbc11340.width == 0 (active)>",
"<NSLayoutConstraint:0x600000647250 'UISV-canvas-connection' UILayoutGuide:0x600001c76a00'UIViewLayoutMarginsGuide'.leading == UITableView:0x7fa9bc0a2e00.leading (active)>",
"<NSLayoutConstraint:0x6000006472f0 'UISV-canvas-connection' UILayoutGuide:0x600001c76a00'UIViewLayoutMarginsGuide'.trailing == UITableView:0x7fa9bc0a2e00.trailing (active)>",
"<NSLayoutConstraint:0x6000006470c0 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x600001c76a00'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':UIStackView:0x7fa9bbc32260 )>",
"<NSLayoutConstraint:0x600000647160 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600001c76a00'UIViewLayoutMarginsGuide']-(8)-|(LTR) (active, names: '|':UIStackView:0x7fa9bbc32260 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000006472f0 'UISV-canvas-connection' UILayoutGuide:0x600001c76a00'UIViewLayoutMarginsGuide'.trailing == UITableView:0x7fa9bc0a2e00.trailing (active)>
I can't seem to figure out what the error is. If someone can point me to the right direction, that'd be extremely helpful, or if there's a different approach, that'd be helpful too.
Here's also a guideline of what the view hierarchy looks like:
UIScrollView
-> UIStackView
-> UITableView
I would strongly suggest that you don't add a table view inside a scroll view since that table view already has a scroll view.
That being said I would add the constraints this way
ScrollView:
Pin it to all corners of the superview
Stack View:
Pin it to the four corners of the the scroll view
Create a height constraint that is equal to the scroll view height
Create a width constraint that is equal to the scroll view width
Table View
Add the table view to the stack view
If you need to add a height constraint to the the table view you need to remove the height constraint of the stack view
If you add additional views to the stack view you will need to add a height constraint to them as well
I realized that I was overthinking on how the designs should be implemented. I've removed the UIStackView, and replaced it with a UITableView as the root instead.
So now the Hierarchy is more:
UITableView
-> SectionHeaderView
-> CustomCells (dequeuedReusable)
I decided to put those extra views onto the section header view at the top, and then used the cells instead. Thank you guys for the suggestion and clearer approach. Much appreciated.
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
I am creating a table view having cells whose height is determined by Auto Layout.
The table view cell has only one subview - An UIImageView which is pinned to the 4 sides of the table view cell.
The image view has a constraint to maintain aspect ratio of 4:3.
The following image shows the view hierarchy and constraints.
The height of the row of the table view is set to automatic as the following screenshot shows.
When the app is run, the table view cell looks as expected, but the following Auto Layout constraint errors are shown in the logs
(
"<NSLayoutConstraint:0x600001d804b0 AppName.NeverClearImageView:0x7f938ce140f0.width == 1.33333*AppName.NeverClearImageView:0x7f938ce140f0.height (active)>",
"<NSLayoutConstraint:0x600001d80460 AppName.NeverClearImageView:0x7f938ce140f0.bottom == UITableViewCellContentView:0x7f938ce04790.bottom (active)>",
"<NSLayoutConstraint:0x600001d80410 H:[AppName.NeverClearImageView:0x7f938ce140f0]-(0)-| (active, names: '|':UITableViewCellContentView:0x7f938ce04790 )>",
"<NSLayoutConstraint:0x600001d82a80 H:|-(0)-[AppName.NeverClearImageView:0x7f938ce140f0] (active, names: '|':UITableViewCellContentView:0x7f938ce04790 )>",
"<NSLayoutConstraint:0x600001d82bc0 V:|-(0)-[AppName.NeverClearImageView:0x7f938ce140f0] (active, names: '|':UITableViewCellContentView:0x7f938ce04790 )>",
"<NSLayoutConstraint:0x600001dbb930 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f938ce04790.height == 125.5 (active)>",
"<NSLayoutConstraint:0x600001db8dc0 'UIView-Encapsulated-Layout-Width' UITableViewCellContentView:0x7f938ce04790.width == 256 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600001d804b0 AppName.NeverClearImageView:0x7f938ce140f0.width == 1.33333*AppName.NeverClearImageView:0x7f938ce140f0.height (active)>
The table view cell looks as expected. Can anyone point out how to resolve this error?
Note - I observe that the above error is not shown if the priority of the aspect ratio is set to 999 instead of 1000. Can anyone point out why this solves the issue?
The case goes like this: I have a form embed in a UIScrollView, in the form there's a part where the user can add N numbers of textField, so if at first I had this:
UITextField - textField1
UIButton - Add
When Add is pressed I want to have this:
UITextField - textField1
UITextField - textField2
UIButton - Add
And although the text field is added, the constraints cannot be satisfied and therefore the UI breaks
The log for that:
[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.
(
"<_UILayoutSupportConstraint:0x1c4c800a0 _UILayoutGuide:0x106ccf4e0.height == 64 (active)>",
"<_UILayoutSupportConstraint:0x1c4c80050 V:|-(0)-[_UILayoutGuide:0x106ccf4e0] (active, names: '|':UIView:0x106ccdc10 )>",
"<_UILayoutSupportConstraint:0x1c4c80ff0 _UILayoutGuide:0x106ccf6d0.height == 0 (active)>",
"<_UILayoutSupportConstraint:0x1c4c801e0 _UILayoutGuide:0x106ccf6d0.bottom == UIView:0x106ccdc10.bottom (active)>",
"<NSLayoutConstraint:0x1c4c80550 UIImageView:0x106cce6c0.height == 5 (active)>",
"<NSLayoutConstraint:0x1c4c80640 UILabel:0x106ccf070'Completa tu Perfil'.height == 24 (active)>",
"<NSLayoutConstraint:0x1c0c886b0 form-view.height == 579 (active, names: form-view:0x10ed307c0 )>",
"<NSLayoutConstraint:0x1c0c8a1e0 V:|-(0)-[form-view] (active, names: form-view:0x10ed307c0, '|':UIScrollView:0x107a37000 )>",
"<NSLayoutConstraint:0x1c0c8a320 V:[form-view]-(0)-[profiles-view] (active, names: profiles-view:0x106ccd430, form-view:0x10ed307c0 )>",
"<NSLayoutConstraint:0x1c4c80af0 V:[_UILayoutGuide:0x106ccf4e0]-(10)-[UILabel:0x106ccf070'Completa tu Perfil'] (active)>",
"<NSLayoutConstraint:0x1c4c80cd0 V:[UILabel:0x106ccf070'Completa tu Perfil']-(8)-[UIImageView:0x106cce6c0] (active)>",
"<NSLayoutConstraint:0x1c4c80d20 V:[UIImageView:0x106cce6c0]-(0)-[UIScrollView:0x107a37000] (active)>",
"<NSLayoutConstraint:0x1c4c80e10 UIImageView:0x106ccddf0.top == profiles-view.top (active, names: profiles-view:0x106ccd430 )>",
"<NSLayoutConstraint:0x1c4c80f00 V:[UIImageView:0x106ccddf0]-(0)-[_UILayoutGuide:0x106ccf6d0] (active)>",
"<NSLayoutConstraint:0x1c0c8bdb0 'UIView-Encapsulated-Layout-Height' UIView:0x106ccdc10.height == 667 (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x1c0c886b0 form-view.height == 579 (active, names: form-view:0x10ed307c0 )>
So, since the height constraint was broken, AutoLayout arrange the elements following the margin constraints which allows the views broke that way.
That being said, the way I am adding the constraints is this:
func addModelButtonAction(_ sender: Any) { // an IBAction
addButton.isHighlighted = false
let last = modelTextFields.last!
let textField = last.createCopy() // extension method for creating a copy of the last textField
modelTextFieldsView.insertSubview(textField, belowSubview: last)
let growth = last.frame.height + 8 // the 8 represents the top spacing between textFields
formViewHeight.constant += growth // increasing height of the view where the form is embeded
modelTextFieldsHeight.constant += growth // increasing height of the view where the textFields are embeded
UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
textField.frame.origin.y += growth // moving new textField below the previous one
}
modelTextFields.append(textField) // array of UITextField to keep track of the textFields in screen
}
And the view's alignment rectangles:
And the view's hierarchy:
What can I do to make this work as expected? I appreciate your help in this, because I've been trying to figure this out without any success.
Thanks in advance!
You have a couple of options to solve this layout issue:
Personally, I might try embedding these views in a UIStackView. The stack view will work to manage the vertical layout for you, allowing you to insert and remove subviews as needed. UIStackView is especially easy to work with from Interface Builder if you use Storyboards.
Alternatively, you could use a UITableView for this layout; it would manage the vertical flow on your behalf, abstracting much of the layout headache from you, though you'd need to manage the data source and cells yourself.
You could probably get this layout to work without either of these by carefully managing the priority of different constraints, allowing some to be broken as the layout changes, but this can be a tedious chore.