Are NSLayoutConstraints animatable?
Just follow this exact pattern:
self.heightFromTop.constant = 550.0f;
[myView setNeedsUpdateConstraints];
[UIView animateWithDuration:0.25f animations:^{
[myView layoutIfNeeded];
}];
where myView
is the view where self.heightFromTop
was added to. Your view is "jumping" because the only thing you did in the animation block was to set the constraint, which does not cause layouts immediately. In your code, the layout happens on the next run loop after you set heightFromTop.constant
, and by that time you are already outside the scope of the animation block.
In Swift 2:
self.heightFromTop.constant = 550
myView.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: {
myView.layoutIfNeeded()
})
How do I animate a NSLayoutConstraint in Swift?
By the time you hit viewDidLoad
, the constraints engine has not yet been applied and the starting location of the views has not yet been established. So, feel free to add the original constraints in viewDidLoad
, but you will want to defer the animateWithDuration
until later in the process (e.g. viewDidAppear
).
For example, let's assume you have some constraint that you added in Interface Builder (IB). You can add an@IBOutlet
reference to it by control-dragging from the constraint in the document outline in the left panel in Interface Builder down to the assistant editor:
Now that you have a reference to that constraint, you can now programmatically alter the constant
value for that constraint (but, again, do this in viewDidAppear
, not viewDidLoad
, if you want to see this animated when the view is presented):
@IBOutlet weak var topConstraint: NSLayoutConstraint!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
topConstraint.constant = 100
UIView.animate(withDuration: 2) {
self.view.layoutIfNeeded()
}
}
The process is the same for programmatically created constraints. Just save a reference to the constraint and then in viewDidAppear
update the constant
and then animate the call to layoutIfNeeded()
.
UIView Animation not working with NSLayoutConstraint?
The animation with constraints could be a little bit tricky. First you need to adjust desired constraints, outside of the animation closure:
NSLayoutConstraint(item: self.placeholder, attribute: .left, relatedBy: .equal, toItem: self.searchBar, attribute: .left, multiplier: 1, constant: 5).isActive = true
Since constraint changes could cause other views change their position, you need ask superview (in the most cases the VC-view) to layout its subviews within the animation closure:
UIView.animate(withDuration: 2, delay: 1, options: UIViewAnimationOptions.curveEaseOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
Therefore the superview adjusts subviews positions for you within the animation block.
NSLayoutConstraint not animating with UIView.animate
You need to relayout the superview
func animate(){
centered = !centered
self.top?.constant = -500
UIView.animate(withDuration: 3) {
self.view.layoutIfNeeded()
}
}
NSLayoutConstraint.constant ignoring animation
You have to first set the completion handler and only then send the message to the animator proxy. Otherwise, it seems that setting the completion handler after the animation started fires it immediately and the constant is removed before the animation has time to finish.
I have just checked this with a piece of simple code:
[NSAnimationContext beginGrouping];
NSAnimationContext.currentContext.duration = animagionDuration;
NSAnimationContext.currentContext.completionHandler = ^{
[self removeConstraint:collapseConstraint];
};
[collapseConstraint.animator setConstant:expandedHeight];
[NSAnimationContext endGrouping];
This works perfectly, but if you set completion handler after -setConstant:
, the animation does not have a chance to run.
Animate NSLayoutConstraints multiplier and/or isActive state
Yes there is suppose that a view1 in storyboard has a width constraint to the main view (self.view in code) like this
view1Width = view * 0.7 + constant
instead of creating 2 constraints and switching between them by changing Active property ORRR [by deactivating current constraint with old multiplier and creating a new one with a new multiplier] leave it 1 constraint and play with it's constant
suppose i want to change view1 multiplier to be 0.9 instead of 0.7
I may do this
self.view1Width.constant += self.view.frame.size.width * 0.2
same you do for subtraction
with this idea you haven't need to be stuck in how to animate active on/off but you still use
self.view.layoutIfNeeded()
Related Topics
Core Data Background Context Best Practice
Swift 2.0 Calendar Components Error
Xcode 8 - Ib Designables - Failed to Render and Update Auto Layout Status, the Agent Crashed
Attempt to Insert Non-Property List Object When Trying to Save a Custom Object in Swift 3
How to Use Any in Codable Type
iOS 11 Navigation Bar Height Customizing
How to Get Uikeyboard Size with iOS
How to Make Uitextview Detect Links for Website, Mail and Phone Number
Force Landscape Orientation in Uiimagepickercontroller
How to Create a Uiview Bounce Animation
How to Change Locale Programmatically with Swift
How to Open File and Append a String in It, Swift
How to Draw a Line Programmatically from a View Controller
Invalid Swift Support/Invalid Implementation of Swift
Cleanest Way of Capturing Volume Up/Down Button Press on iOS 8
Instruments Allocations Track Alloc and Dealloc of Objects of User Defined Classes