How to apply auto layout properly - ios

I have set of images(thumbs) in UITableviewcell. When tapping on each image, a popup(custom view) will be displayed which is a UISCrollview. i am adding all images(big) in Scroll View. So user can scroll to see images.
I am adding UISCrollView to RootViewController's view. so that it covers the entire screen. Below is my code
My Code:
self.mainView = self.superview?.window?.rootViewController?.view
imageScrollView = UIScrollView(frame: CGRectMake(0, 0, self.mainView!.frame.size.width, self.mainView!.frame.size.height))
imageScrollView.delegate = self
self.mainView.addsubview(imageScrollView)
Constraints:
self.mainView!.addConstraint(NSLayoutConstraint(item: imageScrollView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.mainView!, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0.0))
self.mainView!.addConstraint(NSLayoutConstraint(item: imageScrollView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.mainView!, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0))
I got the error in console:
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:0xab1090 h=--- v=--- H:[UIWindow:0xa724f0(768)]>",
"<NSLayoutConstraint:0x1133f450 UIScrollView:0x115723a0.centerY == UIView:0xa49fe0.centerY>",
"<NSAutoresizingMaskLayoutConstraint:0x483cc70 h=--& v=--& UIScrollView:0x115723a0.midY == + 512>",
"<NSAutoresizingMaskLayoutConstraint:0x115b7290 h=-&- v=-&- UIView:0xa49fe0.width == UIWindow:0xa724f0.width>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x1133f450 UIScrollView:0x115723a0.centerY == UIView:0xa49fe0.centerY>
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2014-12-08 01:13:27.379 afipad[349:60b] 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:0xab10c0 h=--- v=--- V:[UIWindow:0xa724f0(1024)]>",
"<NSLayoutConstraint:0x1133f090 UIScrollView:0x115723a0.centerX == UIView:0xa49fe0.centerX>",
"<NSAutoresizingMaskLayoutConstraint:0x115b6dd0 h=--& v=--& UIScrollView:0x115723a0.midX == + 384>",
"<NSAutoresizingMaskLayoutConstraint:0x115b72f0 h=-&- v=-&- UIView:0xa49fe0.height == UIWindow:0xa724f0.height>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x1133f090 UIScrollView:0x115723a0.centerX == UIView:0xa49fe0.centerX>
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
When i check with break point, i got UIWindow size as 768 and 1024 in both portrait and Landscape. When i rotate the screen from Portrait to Landscape, the "imageScrollView" size is 768(width) and 1024(height) instead of 1024x768. What is the actual cause? How can i resolve it.

There are a couple different conflicting things happening here.
First, adding a subview to the root ViewController's view probably isn't going to work because it breaks encapsulation on several levels. Instead, present a new view controller containing your scrollView -- either as a modal or by pushing from self.navigationController -- directly from your table cell.
Second, autolayout constraints on UIScrollviews are kinda counterintuitive. See https://developer.apple.com/library/ios/technotes/tn2154/_index.html for an explanation of how to set them up.
Third, you'll probably need to set translatesAutoresizingMaskIntoConstraints to FALSE in this new viewController. (It explains that in the document, too)
Also, see my sample project for some examples of how to put images and other things inside a scrollView using autolayout:
https://github.com/annabd351/AutolayoutTemplate

Related

How to properly resize the most outside view in a custom keyboard extension ViewController using swift 3?

I have a function that sets the height of a custom keyboard extension, depending on the phone. I originally just tried this in viewDidLoad():
self.view.heightAnchor.constraint(equalToConstant: 100)
This didn't seem to work, so I made a function:
func updateHeightOfView() {
var currentKeyboardInView: String!
if currentViewHeightConstraint != nil {
view.removeConstraint(currentViewHeightConstraint!)
}
currentViewHeightConstraint = NSLayoutConstraint(item: view, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1.0, constant: desiredHeight)
view.addConstraint(currentViewHeightConstraint!)
}
that way when the screen changes it's orientation, I resize the view. The second block of code works perfectly, but it throws warnings of layoutConstraints, so I was wondering why the first block of code isn't working, and if there is an easier way to UPDATE constraints of the height property of a view rather than add and remove them. This view is the most outside view in the viewController.
Here's the warning the second block spits out:
[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:0x608000298b00 App.KeyboardAccessoryView:0x7fdc00b1bfe0.height == 258 (active)>",
"<NSLayoutConstraint:0x600000297e80 'UIView-Encapsulated-Layout-Height' App.KeyboardAccessoryView:0x7fdc00b1bfe0.height == 216 (active)>"
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x608000298b00 App.KeyboardAccessoryView:0x7fdc00b1bfe0.height == 258 (active)>
As much detail you given here according to this I think where ever you set height of this view it is not static constant value but in view didload you are setting constant value for its height. So that's by it is not working.
In second block you are getting warning because may be your view is getting height from more than one way. To check this in updathHeight method just remove the constraint , don't add and try to run.
Exact solution could be given only looking on your constraints.

How to change size of an MKMapView in Swift?

I can't seem to change the size of my MKMapView in Swift. How would one go on about it?
I've tried two different methods but without any luck:
var rect: CGRect = self.view.frame;
rect.origin.y = 0;
self.mapView.frame = rect;
and one where I used constraints and autolayout but it made the app crash. Any ideas?
EDIT:
When I write this code it doesn't crash but writes some warnings in the output:
let height = UIScreen.mainScreen().bounds.height
let width = UIScreen.mainScreen().bounds.width
let widthConstraint = NSLayoutConstraint(item: mapView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: width)
self.view.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: mapView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: height)
self.view.addConstraint(heightConstraint)
The output says:
2016-03-09 18:43:02.697 Map[19782:3177712] 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.
(
"",
""
)
Will attempt to recover by breaking constraint
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints
to catch this in the debugger. The methods in the
UIConstraintBasedLayoutDebugging category on UIView listed in
may also be helpful. Message from debugger:
Terminated due to signal 15
I don't really understand this, any ideas?
In this case you should use
self.mapView.addConstraint(widthConstraint)
and
self.mapView.addConstraint(heightConstraint)
You are trying to add a constraint that belongs to the mapView to its superview, that's not the way it's supposed to be. If you were adding a vertical distance between the mapview and another view you would add it to the superview, but not in this case.
For the constraint warning you try to add constraint without disabling the autorisizing mask into constraint translation.
Try adding this line:
mapView.translatesAutoresizingMaskIntoConstraints = false
Regards

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.

Why are NSLayoutConstraints ignored?

I am experiencing a misunderstanding of mechanics of iOS Layout Constraints. See the code I placed inside viewDidLoad listed below.
var btn = UIButton()
btn.setTitle("i am a button", forState: UIControlState.Normal)
btn.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
btn.backgroundColor = UIColor.lightGrayColor()
btn.sizeToFit()
view.addSubview(btn)
view.addConstraint(
NSLayoutConstraint(item: view,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: btn,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1.0,
constant: 0.0))
view.addConstraint(
NSLayoutConstraint(item: view,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: btn,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1.0,
constant: 0.0))
It seems to me my intention is clear. I want to see a button at the center of a device's screen. But I can see only the following picture though.
And I have an output in project’s console so scary I cannot understand a thing from it.
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) (
"",
"",
"",
"
(Names: '|':UIWindow:0x7fd318551080 )>" )
Will attempt to recover by breaking constraint
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints
to catch this in the debugger. The methods in the
UIConstraintBasedLayoutDebugging category on UIView listed in
may also be helpful. 2015-04-28 23:46:04.516
ConsTest[5966:248434] 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) (
"",
"",
"",
"
(Names: '|':UIWindow:0x7fd318551080 )>" )
Will attempt to recover by breaking constraint
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints
to catch this in the debugger. The methods in the
UIConstraintBasedLayoutDebugging category on UIView listed in
may also be helpful.
Looks like the constraints are treated contradictory and thus ignored at all. I cannot really point out why I can’t just create a button and place it at the center programmatically. Any relevant instruction is much appreciated.
On your UIButton (btn) set translatesAutoresizingMaskIntoConstraints = false
E.g.
btn.translatesAutoresizingMaskIntoConstraints = false
Recommended reading: Adopting Auto Layout

The ghost of NSLayoutConstraint haunts my view hierarchy?

I'm trying to programmatically modify autolayout constraints to move a table view up, but only for an iPhone 6 Plus in landscape mode, because I couldn't achieve the precise visual effect I wanted on all devices using Xcode 6.2 beta 3 Interface Builder's autolayout (got it right from IB for the other supported devices/orientations. Just that iPhone 6 Plus is a bit of an outlier between an iPhone and an iPad, thus a little trickier)
One constraint I remove seems to be deleted after removal (e.g. disappears from the containing view's constraints, as expected), however, the layout manager still seems to finds it and warns that it is a conflict with other constraints and breaks a constraint at runtime with the fortunate result that the app produces the intended visual result, but the unfortunate side-effect of an ugly console warning message, that I want to fix, because it's ugly and Apple documentation blames such warnings user code bug(s).
My code intercepts orientation change (only on iPhone 6 Plus),
and then:
=============
• Iterates over constraints in tableview's owner view
• Prints properties of any constraint with an attribute of .Top
• Removes Center Y constraint referenced via IBOutlet, for the tableview
• Removes constraint with .Top attribute
• Adds new .Top attribute with a different multiplier
============
Here is the swift code in my View Controller:
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
switch(toInterfaceOrientation) {
case .LandscapeLeft:
fallthrough
case .LandscapeRight:
var deviceType = UIDevice().deviceType
if (deviceType == .iPhone6plus || deviceType == .simulator) {
if centerYconstraint != nil {
self.view.removeConstraint(centerYconstraint)
centerYconstraint = nil
for constraint in self.view.constraints() {
if (constraint.firstItem as NSObject == self.tableView) {
if (constraint.firstAttribute == NSLayoutAttribute.Top) {
println("found item \(constraint)")
let view1 = constraint.firstItem as UIView
let attr1 = constraint.firstAttribute
let view2 = constraint.secondItem as UIView
let attr2 = constraint.secondAttribute
let relation = constraint.relation
let constant = constraint.constant
let newConstraint = NSLayoutConstraint(
item: view1,
attribute: attr1,
relatedBy: relation,
toItem: view2,
attribute: attr2,
multiplier: 0.02,
constant: constant)
self.view.removeConstraint(constraint as NSLayoutConstraint)
self.view.addConstraint(newConstraint)
self.view.layoutIfNeeded()
}
}
}
}
}
default:
break
}
}
Here is Xcode simulator's output. Notice the first line "found item" where I print the constraint I delete.
But you can see the same view1 and view2, multiplier and attribute in the list of potential contflicts layout manager complains about afterward. That's what I'm confused about.
found item <NSLayoutConstraint:0x7f8a05101bb0 UITableView:0x7f8a05853000.top == 0.03*_UILayoutGuide:0x7f8a035517e0.top>
2015-01-03 14:36:35.290 Interphase[46388:74323123] 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)
(
"<NSLayoutConstraint:0x7f8a0354da40 V:[UITableView:0x7f8a05853000(336)]>",
"<_UILayoutSupportConstraint:0x7f8a0514df70 V:[_UILayoutGuide:0x7f8a035517e0(49)]>",
"<_UILayoutSupportConstraint:0x7f8a051908e0 _UILayoutGuide:0x7f8a035517e0.bottom == UIView:0x7f8a03551480.bottom>",
"<NSLayoutConstraint:0x7f8a051b53d0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7f8a03551480(414)]>",
"<NSLayoutConstraint:0x7f8a050d9080 UITableView:0x7f8a05853000.top == 0.02*_UILayoutGuide:0x7f8a035517e0.top>",
"<NSLayoutConstraint:0x7f8a0354ef80 UITableView:0x7f8a05853000.centerY == UIView:0x7f8a03551480.centerY>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f8a0354da40 V:[UITableView:0x7f8a05853000(336)]>
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-01-03 14:36:56.720 Interphase[46388:74323123] 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:0x7f8a0514df70 V:[_UILayoutGuide:0x7f8a035517e0(49)]>",
"<_UILayoutSupportConstraint:0x7f8a051908e0 _UILayoutGuide:0x7f8a035517e0.bottom == UIView:0x7f8a03551480.bottom>",
"<NSLayoutConstraint:0x7f8a05101bb0 UITableView:0x7f8a05853000.top == 0.03*_UILayoutGuide:0x7f8a035517e0.top>",
"<NSLayoutConstraint:0x7f8a051b53d0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7f8a03551480(736)]>",
"<NSLayoutConstraint:0x7f8a050d9080 UITableView:0x7f8a05853000.top == 0.02*_UILayoutGuide:0x7f8a035517e0.top>"
)
Adding and removing constraints to a view is a bit flaky. It's never entirely clear which view they should be added to and then it makes it hard to find later when you want to remove it.
A better solution is to keep a reference to the constraint(s) you care about (either as outlets if you're doing it from interface builder, or just store them in properties) and then activate or deactivate them as required.
Activating constraints instead of adding them also prevents you having to decide which is the appropriate view to add them to - the system does this automatically.

Resources