iOS .addConstraint only works once - ios

I'm making a custom keyboard for iOS8 and on the Apple Developer docs it says that you can change the height of a custom keyboard anytime after the initial primary view draws on the screen. And it says to do this you should use the .addConstaint() method.
Here's a link:
https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/Keyboard.html
I'm using Swift. The initial height of the keyboard is 215 pixels. I have a swipe up gesture that increases the height to 350 pixels. Which works as expected. And a swipe down that changes the height to 300 pixels.
That all works ok, but the problem is it only works once. I swipe up and the height increases, I swipe down and it decreases, but if I swipe up again nothing happens. If I swipe down again nothing happens.
So I'd be greatful if anyone could take a look at my two functions and tell me what I'm doing wrong.
Here's the code:
// IBActions
#IBAction func action1(sender: AnyObject) {
if topboxvisible == false {
topboxvisible = true
UIView.animateWithDuration(0.08, delay: 0, options: .CurveEaseIn, animations: {
self.topbox.frame.offset(dx: 0, dy: 40)
}, completion: nil)
}
let expandedHeight:CGFloat = 300
let heightConstraint = NSLayoutConstraint(item:self.view,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 0.0,
constant: expandedHeight)
self.view.removeConstraint(heightConstraint)
self.view.addConstraint(heightConstraint)
}
#IBAction func action2(sender: AnyObject) {
if topboxvisible == true {
topboxvisible = false
UIView.animateWithDuration(0.08, delay: 0, options: .CurveEaseOut, animations: {
self.topbox.frame.offset(dx: 0, dy: -40)
}, completion: nil)
}
let expandedHeight:CGFloat = 350
let heightConstraint = NSLayoutConstraint(item:self.view,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 0.0,
constant: expandedHeight)
self.view.removeConstraint(heightConstraint)
self.view.addConstraint(heightConstraint)
}

Your removeConstraint calls aren't doing anything, because the constraint you just created (in the previous line of code) isn't in the view. So what you're doing here is adding more constraints every time, from what I can see. I imagine this is leading to multiple conflicting constraints—do you see any NSConstraint warnings popping out in the console log while you're running the code?
Try this: create both your height constraints in advance, and store them in instance variables. In action1, remove the 350-high constraint, and add the 300. In action2, remove the 300, and add the 350.

Related

how to set height constraint in IBDesignable file?

I need to make an IBDesignable to make a custom navigation bar file that will adjust the height of the view based on the iPhone type. if the iPhone has top notch like iPhone X,XR, then the height contraint will be 88, otherwise for iPhone 8 that does not has top notch, the height will be 64.
I need to set the height contraint, not the layer height. here is the code I use but it fails to update the height contraint
import UIKit
#IBDesignable
class CustomParentNavigationBarView: UIView {
override func awakeFromNib() {
super.awakeFromNib()
self.setHeight()
}
func setHeight() {
let deviceHasTopNotch = checkHasTopNotchOrNot()
var heightConstraint = NSLayoutConstraint()
if deviceHasTopNotch {
heightConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 88)
} else {
heightConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 64)
}
heightConstraint.isActive = true
self.addConstraint(heightConstraint)
}
func checkHasTopNotchOrNot() -> Bool {
if #available(iOS 11.0, tvOS 11.0, *) {
// with notch: 44.0 on iPhone X, XS, XS Max, XR.
// without notch: 20.0 on iPhone 8 on iOS 12+.
return UIApplication.shared.delegate?.window??.safeAreaInsets.top ?? 0 > 20
}
return false
}
}
the result should be something like this (red view), the height of the red view should change according to iPhone type, either 88 or 64
for the initial value, I set the autolayout of the view in storyboard like this
There are two problems that I can see.
You are not activating the constraints. Add this line
heightConstraint.isActive = true
You are calling SetHeight multiple times. Each time, a constraint is added. This will lead to constraint conflicts and poor behavior. Instead, just create the constraint once and store it as a member.

How do I add constraints to a subview loaded from a nib file?

I'm trying to load a sub view on to every single page of my app from a nib file. Right now I'm using a somewhat unusual approach to loading this sub view in that I am doing it through an extension of UIStoryboard (probably not relevant to my problem, but I'm not sure). So this is how the code looks when I load the nib file:
extension UIStoryboard {
public func appendCustomView(to viewController: UIViewController) {
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
viewController.view.addSubview(myCustomSubview)
}
}
}
This code does what it's supposed to do and adds "MyCustomSubview" to the view controller (I won't go in to detail on exactly how this method gets called because it works so it doesn't seem important). The problem is I can't for the life of me figure out how to add constraints that effect the size of myCustomSubview. I have tried putting code in the function I showed above as well as in the MyCustomSubview swift file to add constraints but no matter what I do the subview never changes.
Ideally the constraints would pin "MyCustomSubview" to the bottom of the ViewController, with width set to the size of the screen and a hard coded height constraint.
Here are the two main methods I tried (with about 100 minor variations for each) that did NOT work:
Method 1 - Add constraint directly from "appendCustomView"
public func appendCustomView(to viewController: UIViewController) {
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
let top = NSLayoutConstraint(item: myCustomSubview, attribute: .top, relatedBy: .equal
, toItem: viewController.view, attribute: .top, multiplier: 1, constant: 50.0)
viewController.view.addSubview(myCustomSubview)
viewController.view.addConstraint(top)
}
}
Method 2 - Add constraint outlets and setter method in MyCustomSubview
class MyCustomSubview: UIView {
#IBOutlet weak var widthConstraint: NSLayoutConstraint!
#IBOutlet weak var heightConstraint: NSLayoutConstraint!
func setConstraints(){
self.widthConstraint.constant = UIScreen.main.bounds.size.width
self.heightConstraint.constant = 20
}
}
And call setter method in "appendCustomView"
public func appendCustomView(to viewController: UIViewController) {
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
myCustomSubview.setConstraints()
viewController.view.addSubview(myCustomSubview)
}
}
(*note: the actual constraints of these examples are irrelevant and I wasn't trying to meet the specs I mentioned above, I was just trying to make any sort of change to the view to know that the constraints were updating. They weren't.)
Edit : Changed "MyCustomNib" to "MyCustomSubview" for clarity.
When you add constraints onto a view from a Nib, you have to call yourView.translatesAutoresizingMaskIntoConstraints = false, and you also need to make sure that you have all 4 (unless it's a label or a few other view types which only need 2) constraints in place:
Here's some sample code that makes a view fill it's parent view:
parentView.addSubview(yourView)
yourView.translatesAutoresizingMaskIntoConstraints = false
yourView.topAnchor.constraint(equalTo: parentView.topAnchor).isActive = true
yourView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor).isActive = true
yourView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor).isActive = true
yourView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor).isActive = true
Edit: I've actually come around to perferring this method of adding NSLayoutConstraints, even though the results are the same
NSLayoutConstraint.activate([
yourView.topAnchor.constraint(equalTo: parentView.topAnchor),
yourView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor),
yourView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor),
yourView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor),
])
For anyone who comes across this in the future, this is the solution I came up with by tweaking this answer a little bit
Add a setConstraints(withRelationshipTo) method in the swift class that corresponds to the nib file:
class MyCustomSubview: UIView {
func setConstraints(withRelationshipTo view: UIView){
self.translatesAutoresizingMaskIntoConstraints = false
// Replace with your own custom constraints
self.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
self.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
self.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
self.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}
}
Then call the setConstraints method after you add the nib file to the view (probably in viewWillAppear or viewDidLoad of a view controller )
class MyViewController: UIViewController {
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(animated)
if let myCustomSubview = Bundle.main.loadNibNamed("MyCustomSubview", owner: nil, options: nil)![0] as? MyCustomSubview {
let view = self.view // Added for clarity
view.addSubview(myCustomSubview)
myCustomSubview.setConstraints(withRelationshipTo: view)
}
}
}
You can use this extension for anywhere you're going to add a subview to a existing UIView.
extension UIView {
func setConstraintsFor(contentView: UIView, left: Bool = true, top: Bool = true, right: Bool = true, bottom: Bool = true) {
contentView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(contentView)
var constraints : [NSLayoutConstraint] = []
if left {
let constraintLeft = NSLayoutConstraint(item: contentView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0)
constraints.append(constraintLeft)
}
if top {
let constraintTop = NSLayoutConstraint(item: contentView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0)
constraints.append(constraintTop)
}
if right {
let constraintRight = NSLayoutConstraint(item: contentView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0)
constraints.append(constraintRight)
}
if bottom {
let constraintBottom = NSLayoutConstraint(item: contentView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0)
constraints.append(constraintBottom)
}
self.addConstraints(constraints)
}
}
You can call this method like this:
containerView.setConstraintsFor(contentView: subView!, top: false)
This will add subView to the containerView and constraint to all sides except top side.
You can modify this method to pass left, top, right, bottom Constant value if you want.

View size is automatically being set to window size, when one of window's subview is removed

I have two views one of them is the mainVideoView (Grey color) and the other is the subVideoView (red color). Both of them are the subViews of UIApplication.shared.keyWindow.
When I try and minimise them (using func minimiseOrMaximiseViews, they get minimised (as shown in the below image).
After which, I would like to remove the subVideoView from the window. The moment I try and remove the subVideoView (using func removeSubVideoViewFromVideoView() called from func minimiseOrMaximiseViews), the mainVideoView enlarges to the full screen size, I am not sure why this is happening, I want it to stay at the same size.
Could someone please advise/ suggest how I could achieve this ?
This is how I am setting up the views
func configureVideoView(){
videoView.backgroundColor = UIColor.darkGray
videoView.tag = 0 // To identify view during animation
// ADDING TAP GESTURE TO MAXIMISE THE VIEW WHEN ITS SMALL
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(gestureRecognizer:)))
videoView.addGestureRecognizer(tapGestureRecognizer)
// ADDING PAN GESTURE RECOGNISER TO MAKE VIDEOVIEW MOVABLE INSIDE PARENT VIEW
videoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.dragView)))
guard let window = UIApplication.shared.keyWindow else{
return
}
window.addSubview(videoView)
videoView.translatesAutoresizingMaskIntoConstraints = false
let viewsDict = ["videoView" : videoView] as [String : Any]
// SETTING CONSTRAINTS
window.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[videoView]|", options: [], metrics: nil, views: viewsDict))
window.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[videoView]|", options: [], metrics: nil, views: viewsDict))
window.layoutIfNeeded() // Lays out subviews immediately
window.bringSubview(toFront: videoView) // To bring subView to front
print("Videoview constraints in configureVideoView \(videoView.constraints)")
}
func configureSubVideoView(){
subVideoView.backgroundColor = UIColor.red
subVideoView.tag = 1 // To identify view during animation
subVideoView.isHidden = true
// Adding Pan Gesture recogniser to make subVideoView movable inside parentview
subVideoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.dragView)))
// Constraining subVideoView to window to ensure that minimising and maximising animation works properly
constrainSubVideoViewToWindow()
}
func constrainSubVideoViewToWindow(){
//self.subVideoView.setNeedsLayout()
guard let window = UIApplication.shared.keyWindow else{
print("Window does not exist")
return
}
guard !window.subviews.contains(subVideoView)else{ // Does not allow to go through the below code if the window already contains subVideoView
return
}
if self.videoView.subviews.contains(subVideoView){ // If videoView contains subVideoView remove subVideoView
subVideoView.removeFromSuperview()
}
window.addSubview(subVideoView)
// Default constraints to ensure that the subVideoView is initialised with maxSubVideoViewWidth & maxSubVideoViewHeight and is positioned above buttons
let bottomOffset = buttonDiameter + buttonStackViewBottomPadding + padding
subVideoView.translatesAutoresizingMaskIntoConstraints = false
let widthConstraint = NSLayoutConstraint(item: subVideoView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1.0, constant: maxSubVideoViewWidth)
let heightConstraint = NSLayoutConstraint(item: subVideoView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1.0, constant: maxSubVideoViewHeight)
let rightConstraint = NSLayoutConstraint(item: subVideoView, attribute: .trailing, relatedBy: .equal, toItem: window, attribute: .trailing, multiplier: 1.0, constant: -padding)
let bottomConstraint = NSLayoutConstraint(item: subVideoView, attribute: .bottom, relatedBy: .equal, toItem: window, attribute: .bottom, multiplier: 1.0, constant: -bottomOffset)
var constraintsArray = [NSLayoutConstraint]()
constraintsArray.append(widthConstraint)
constraintsArray.append(heightConstraint)
constraintsArray.append(rightConstraint)
constraintsArray.append(bottomConstraint)
window.addConstraints(constraintsArray)
window.layoutIfNeeded() // Lays out subviews immediately
subVideoView.setViewCornerRadius()
window.bringSubview(toFront: subVideoView) // To bring subView to front
}
This is how I am animating views and removing subVideoView
func minimiseOrMaximiseViews(animationType: String){
let window = UIApplication.shared.keyWindow
let buttonStackViewHeight = buttonsStackView.frame.height
if animationType == "maximiseView" {
constrainSubVideoViewToWindow()
}
UIView.animate(withDuration: 0.3, delay: 0, options: [],
animations: { [unowned self] in // "[unowned self] in" added to avoid strong reference cycles,
switch animationType {
case "minimiseView" :
self.hideControls()
// Minimising self i.e videoView
self.videoView.frame = CGRect(x: self.mainScreenWidth - self.videoViewWidth - self.padding,
y: self.mainScreenHeight - self.videoViewHeight - self.padding,
width: self.videoViewWidth,
height: self.videoViewHeight)
// Minimising subVideoView
self.subVideoView.frame = CGRect(x: self.mainScreenWidth - self.minSubVideoViewWidth - self.padding * 2,
y: self.mainScreenHeight - self.minSubVideoViewHeight - self.padding * 2,
width: self.minSubVideoViewWidth,
height: self.minSubVideoViewHeight)
window?.layoutIfNeeded()
self.videoView.setViewCornerRadius()
self.subVideoView.setViewCornerRadius()
print("self.subVideoView.frame AFTER setting: \(self.subVideoView.frame)")
default:
break
}
}) { [unowned self] (finished: Bool) in // This will be called when the animation completes, and its finished value will be true
if animationType == "minimiseView" {
// **** Removing subVideoView from videoView ****
self.removeSubVideoViewFromVideoView()
}
}
}
func removeSubVideoViewFromVideoView(){
//self.subVideoView.setNeedsLayout()
guard let window = UIApplication.shared.keyWindow else{
return
}
guard !self.videoView.subviews.contains(subVideoView)else{ // Does not allow to go through the below code if the videoView already contains subVideoView
return
}
if window.subviews.contains(subVideoView) { // removing subVideoView from window
subVideoView.removeFromSuperview() // *** CAUSE OF ISSUE ***
}
guard !window.subviews.contains(subVideoView) else{
return
}
videoView.addSubview(subVideoView)
}
The videoView and subVideoView are layout by Auto Layout. In Auto Layout if you want to change the frame, you have to update the constraints.
Calling removeFromSuperView will removes any constraints that refer to the view you are removing, or that refer to any view in the subtree of the view you are removing. This means the auto layout system will to rearrange views.

How to add NSConstraints to UITextView in Swift 3

So I have successfully converted almost all my project to Swift 3 besides from one View Controller where I manually add constraints.
I was getting errors for
view.addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(textView)
let views = ["textView": textView]
var constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-70-[textView]-8-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[textView]-8-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)
NSLayoutConstraint.activate(constraints)
So I changed it to
textView.translatesAutoresizingMaskIntoConstraints = true
view.addSubview(textView)
textView.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
textView.autoresizingMask = [UIViewAutoresizing.flexibleLeftMargin, UIViewAutoresizing.flexibleRightMargin, UIViewAutoresizing.flexibleTopMargin, UIViewAutoresizing.flexibleBottomMargin]
All I am trying to do is add a UITextView to a UIView in a view controller so it takes up the entire height and width and stays vertically and horizontally in the centre. I'm clearly missing something obvious with my updated code and am unsure why my previous code was refusing to run as I worked in Swift 2.2.
Can anyone answer the correct way of adding constraints in Swift 3 ?
UPDATE:
Here's the error from my original code which was converted to Swift 3.0
2016-09-06 22:08:38.751636 APPNAME[570:65129] -[_SwiftValue
nsli_superitem]: unrecognized selector sent to instance 0x17044a0e0
2016-09-06 22:08:38.752963 APPNAME[570:65129] * Terminating app due
to uncaught exception 'NSInvalidArgumentException', reason:
'-[_SwiftValue nsli_superitem]: unrecognized selector sent to instance
0x17044a0e0'
* First throw call stack: (0x18430c1c0 0x182d4455c 0x184313278 0x184310278 0x18420a59c 0x184d42104 0x184d40948 0x184d3f79c
0x184d3f340 0x100221ec0 0x1002289ac 0x100228be8 0x18a0e5b08
0x18a19f4cc 0x18a19f3a4 0x18a19e6ec 0x18a19e138 0x18a19dcec
0x18a19dc50 0x18a0e2c78 0x1875ab40c 0x1875a00e8 0x18759ffa8
0x18751cc64 0x1875440d0 0x18a0d8348 0x1842b97dc 0x1842b740c
0x1842b789c 0x1841e6048 0x185c67198 0x18a150bd0 0x18a14b908
0x100171a04 0x1831c85b8) libc++abi.dylib: terminating with uncaught
exception of type NSException (lldb)
I had this error at the last line of the following code:
scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(scrollView)
contentView = UIView()
contentView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(contentView)
let viewDict = [
"contentView": contentView,
"scrollView": scrollView,
]
let vFormat = "V:|[contentView]|"
let constraints = NSLayoutConstraint.constraints(withVisualFormat: vFormat, options: [], metrics: nil, views: viewDict)
When I set the debugger at the last line, it shows the viewDict type as [String: UIView?] (notice the optional here).
The error does NOT occur when I change the declaration as follows:
let viewDict: [String: UIView] = [
Your first code sample has a syntax error in this line:
textView.addConstraints(constraints: [NSLayoutConstraint])
Presumably it's trying to create an empty array, but there's no point in adding an empty array of constraints, so just delete the line.
Note that your first code sample (with the erroneous line removed) doesn't meet your requirement (“takes up the entire height and width and stays vertically and horizontally in the centre”). You're specifying margins, so the text view won't take up the entire height and width, and the vertical margins are asymmetric, so it won't be centred vertically.
The problem in your second code sample is that you're using the wrong mask. For example, .flexibleLeftMargin tells the system to allow the distance between the left edge of view and the left edge of textView to change, but that is the opposite of what you want.
This should do what you want:
textView.frame = view.bounds
textView.autoresizingMask = [ .flexibleWidth, .flexibleWidth ]
If you want margins, set the frame like this:
var frame = view.bounds.insetBy(dx: 8, dy: 0)
frame.origin.y += 70
frame.size.height -= 78
textView.frame = frame
Note that the size of view must already be at least 16 by 78.
If you want to keep using translatesAutoresizingMaskIntoConstraints=false, rather than the accepted answer, I note the following:
1) I get the errors you get when I generate NSLayoutConstraints using the visual formatting approach - code that compiled file in iOS9.3 SDK and ran fine on devices even those running iOS10 - building with iOS10 SDK crashes with your errors
2) If you change this to manually create the NSLayoutConstraints, e.g. similar to this, then it works as expected:
var allConstraints = [NSLayoutConstraint]()
allConstraints.append(NSLayoutConstraint(item: slideView, attribute: .left, relatedBy: .equal, toItem: slideButton, attribute: .left, multiplier: 1.0, constant: 0.0))
allConstraints.append(NSLayoutConstraint(item: slideView, attribute: .right, relatedBy: .equal, toItem: slideButton, attribute: .right, multiplier: 1.0, constant: 0.0))
allConstraints.append(NSLayoutConstraint(item: slideView, attribute: .top, relatedBy: .equal, toItem: slideButton, attribute: .top, multiplier: 1.0, constant: 0.0))
allConstraints.append(NSLayoutConstraint(item: slideView, attribute: .bottom, relatedBy: .equal, toItem: slideButton, attribute: .bottom, multiplier: 1.0, constant: 0.0))
NSLayoutConstraint.activate(allConstraints)
I don't know what the issue with the more elegant-looking visual formatting, but it appears bust at the moment (or there has been a change to the order of view layout code in iOS between 9.3 and 10).

can an NSLayoutConstraint be re-activated?

I have a result container that a user can expend and contract. I'd like to remove a constraint and add a new one. Clicking on it works fine but clicking a second time (ie setting newConstraint.active=false and resultTopConstraint=true causes it to crash). I have the following:
#IBAction func toggleResultContainer(sender: AnyObject) {
isResultsOpen = !isResultsOpen
//resultTopConstraint.constant = isResultsOpen ? -300.0 : 0.0
self.view.sendSubviewToBack(searchView)
let newConstraint = NSLayoutConstraint(
item: resultsContainer,
attribute: .Top,
relatedBy: .Equal,
toItem: resultsContainer.superview!,
attribute: .Top,
multiplier: 1.0,
constant: 30.0
)
if(isResultsOpen){
resultTopConstraint.active = false
newConstraint.active = true
}else{
resultTopConstraint.active = true
newConstraint.active = false
}
UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 10.0, options: .CurveEaseIn, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
and get the Unable to simultaneously satisfy constraints.
Should the above code work and this is really a simultaneously satisfy constraints issue? I have tried setting the constraint
#IBOutlet var resultTopConstraint: NSLayoutConstraint!
to both weak and strong (per https://stackoverflow.com/a/28717185/152825) but doesn't seem to have an effect. A
Try this:
if (isResultsOpen) {
NSLayoutConstraint.deactivateConstraints([resultTopConstraint])
NSLayoutConstraint.activateConstraints([newConstraint])
} else {
NSLayoutConstraint.deactivateConstraints([newConstraint])
NSLayoutConstraint.activateConstraints([resultTopConstraint])
}

Resources