How to Animate a Uiview with Constraints in Swift

trying to animate a constraint in swift

You need to first change the constraint and then animate the update.

This should be in the superview.

self.nameInputConstraint.constant = 8

Swift 2

UIView.animateWithDuration(0.5) {
self.view.layoutIfNeeded()
}

Swift 3, 4, 5

UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
}

How to animate UIView using constraint from bottom to top?

I have pointed out a few things via comments, read the comment and you will understand what is the issue in your code, check below code.

=> your code : overlay!.addSubview(contentView)

   @objc func showToastViewWithAnimation(viewController: Any) {
if let vc = viewController as? ViewController {
//vc.view.layoutIfNeeded() - this is not required before updating constraint value
self.bottomConstraint.constant = -20 //update contstraint outside of the animation block
UIView.animate(withDuration: 0.8) {
//vc.view.layoutIfNeeded()
self.overlay?.layoutIfNeeded() //you needs to layout the overlay view, as your other toast views are added in overlay view and not in view of viewcontroller as per your code
}
}
}

Swift - Animate Constraints in Custom UIView

The reason why your initial post is not working is that you called your first layoutIfNeeded() after the constraint changes. When your animation block is executed, there's no changes to be animated at all.

It does not matter whether you change the constraints in or out of the animation block.

The common steps are:

  1. Call layoutIfNeeded() on the rootest view that your constraints may affect. In your case, self is ok because all the involving constraints are for the subviews. In some cases, you might change a constraint for the self view, then you need to call layoutIfNeeded on its superview.
  2. Make your constraint changes: modify constant property, activate/deactivate constraints, etc.
  3. Call layoutIfNeeded() in a animation block on the same view as you did in the first step.

Please try the following alternative:

func playAnimation() {
// Request a layout to clean pending changes for the view if there's any.
self.layoutIfNeeded()

// Make your constraint changes.
listLeadingConstraint.constant += (listImageView.frame.size.width * ratioMultiplier)
listTrailingConstraint.constant += (listImageView.frame.size.width * ratioMultiplier)
checkmarkLeadingConstraint.constant += (checkmarkImageView.frame.size.width * ratioMultiplier)
checkmarkTrailingConstraint.constant += (checkmarkImageView.frame.size.width * ratioMultiplier)

UIView.animate(withDuration: 3.0) {
// Let your constraint changes update right now.
self.layoutIfNeeded()
}
}

How to animate a UIImage constraints in Swift 4

First of all you have to drag and drop your constraint into your view controller, to make an outlet. The same way you are doing it with UIImageView or UITableView, etc.

Actually, for those who have watched WWDC (2014 I guess), Apple have explained how to animate UI in the proper way.

Firstly, you have to call layoutIfNeeded() method to make sure that everything on your view have laid out. After you can change your constraint and right after that in your animation block you call layoutIfNeeded() method to layout your constraint with the new value.

So code should look like that:

view.layoutIfNeeded() // to make sure your view have laid out

self.constraint.constant = //change your constant to any value

UIView.animate(withDuration: 1.0) {
self.view.layoutIfNeeded() //layout your constraint with the new value
}

How animate UIView height constraint in Swift programmatically without making an IBOutlet?

The issue in your code is that you are trying to reactivate another constraint that describes the height of myView, by saying (in expandMenu()):

myView.heightAnchor.constraint(equalToConstant: 300).isActive = true

I would assume that you are getting a runtime warning similar to:

[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:0x60400008e5b0 UIView:0x7fa16a419450.height == 100 (active)>",
"NSLayoutConstraint:0x608000097e30 UIView:0x7fa16a419450.height == 300 (active)>"
)

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.

means that myView already has a constraint for height, which is (in viewDidLoad()):

myView.heightAnchor.constraint(equalToConstant: 100).isActive = true

What you should do instead is to change the constant value of the same constraint instead. You could achieve it like this:

Declare a NSLayoutConstraint as instance variable:

var myViewHeightConstraint: NSLayoutConstraint!

and in viewDidLoad():

myViewHeightConstraint = NSLayoutConstraint(item: myView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: 100)
myViewHeightConstraint.isActive = true

instead of:

myView.heightAnchor.constraint(equalToConstant: 100).isActive = true

Finally, in expandMenu():

myViewHeightConstraint.constant = 300

instead of:

myView.heightAnchor.constraint(equalToConstant: 300).isActive = true

Output:

Sample Image


Furthermore:

If you are aiming to let the same button to achieve the expand/collapse behavior, you would need to simply implement it as (in expandMenu()):

myViewHeightConstraint.constant = myViewHeightConstraint.constant == 300 ? 100 : 300

Width constraint change with UIView animation

I achieved desired result by changing view.center.x . I tried to change leading constraint and width but it didn't work out. I also happen to change width of my view but it happens without animation and before/after for expand/collapse respectively. So here is my code:

self.snp.updateConstraints({(make) in
make.width.equalTo(150.0)
})

UIView.animate(withDuration: 0.2,
animations: {
self.center.x -= 90
self.layoutIfNeeded()
}, completion: nil)

And reverse :

UIView.animate(withDuration: 0.2,
animations: {
self.center.x += 90
self.layoutIfNeeded()
}, completion: nil)

self.snp.updateConstraints({(make) in
make.width.equalTo(30.0)
})

Animation is a bit rough when it comes to collapsing but works just fine for expanding. Still appreciate any suggestion.

Simple slide up animation on UIView using NSLayoutConstraints

good day I usually work with transform property for move one view from x position to y portion, please check this example.


class ViewController: UIViewController {

let button : UIButton = {
let button = UIButton(type: .custom)
button.setTitle("Button", for: .normal)
button.backgroundColor = .gray
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()

let customView : UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .red
return view
}()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

view.addSubview(button)
view.addSubview(customView)
NSLayoutConstraint.activate([
button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
customView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
customView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
customView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
customView.heightAnchor.constraint(equalToConstant: 100)
])
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
setupAnimationCustomView()
}

private func setupAnimationCustomView(){
UIView.animate(withDuration: 1, delay: 0 , options: .curveEaseOut, animations: {
print(self.button.frame.origin.y)
let translationY = self.view.frame.height - self.button.frame.origin.y - self.button.frame.height - self.customView.frame.height - 8
self.customView.transform = CGAffineTransform(translationX: 0, y: translationY * (-1))

}, completion: nil)
}

}

on the animation I calculate the distance that I need to move my customView.

How to animate a UIView with constraints in Swift?

What you can do is to add the following code in your viewDidAppear method. You firstly make a IBOutlet property of your view's center Y constraint, and then change its constant value.

self.centerYConstraint.constant = 500.0
self.view.layoutIfNeeded()

UIView.animateWithDuration(Double(0.5), animations: {
self.centerYConstraint.constant = 0
self.view.layoutIfNeeded()
})

Swift animation with constraint

Yes this is possible. You can do something like this:

func AnimateHeight() {
UIView.animateWithDuration(1.5, animations: {
self.heightCons.constant = 250 // Some value
self.view.layoutIfNeeded()
})
}

Where self.heightCons is an IBOutlet to the height constraint on the UIView.

If you don't use storyboards you can check out how to create layout constraints programmatically.

For info on Core Animation and Auto layout: Combining autolayout with core animation



Related Topics



Leave a reply



Submit