UIViewAnimation with constraint not working in Swift - swift

I am trying to create an animation where I want to slide a uiview from right to left once parent UIViewController has loaded although I am able to display the view but the animation is not working. My code for animation:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.isOpaque = false
UIView.animate(withDuration: 1.0, delay: 1.0, options: .curveEaseOut, animations: {
self.contentXConstraint.constant = 500
self.contentXConstraint.constant = 80
}) { (status) in
}
}
I have displayed the parent view controller as presented viewcontroller:
present(navController, animated: false, completion: nil)

You forgot self.view.layoutIfNeeded()
self.contentXConstraint.constant = 500
self.contentXConstraint.constant = 80
UIView.animate(withDuration: 1.0, delay: 1.0, options: .curveEaseOut, animations: {
self.view.layoutIfNeeded()
}) { (status) in
}
from https://developer.apple.com/documentation/uikit/uiview/1622507-layoutifneeded
Use this method to force the view to update its layout immediately. When using Auto Layout, the layout engine updates the position of views as needed to satisfy changes in constraints

Move your animation code from viewDidAppear to viewDidLayoutSubviews

You need to add layoutIfNeeded() method after updating constraints
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.isOpaque = false
UIView.animate(withDuration: 1.0, delay: 1.0, options: .curveEaseOut, animations: {
self.contentXConstraint.constant = 500
self.contentXConstraint.constant = 80
self.view.layoutIfNeeded()
}) { (status) in
}
}

Related

Constraint animation doesnt animate y position change

This code is to expand a label by disabling the constraint which is keeping it at a max height of 54 to a full size. It works as it should but it jumps to the new y position straight away (without animating) and changes frame height after which makes it look like it jumps before animating
#IBOutlet var descriptionHeightConstraint: NSLayoutConstraint!
#IBAction func toggleFullDescription(_ sender: Any) {
if descriptionHeightConstraint.isActive {
self.layoutIfNeeded()
descriptionHeightConstraint.isActive = false
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
//seeMoreButton.setTitle("See less", for: .normal)
} else {
self.layoutIfNeeded()
descriptionHeightConstraint.isActive = true
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
//seeMoreButton.setTitle("See more", for: .normal)
}
}
Video of the issue

UIButton resize animation is not animating

I'm trying to make that my button double its size using the UIView animation, but for some reason it is not working it the size goes right, but no animated.
The function that should animate the button resizing
Irrelevant code above
#objc func createButtonPressed(){
//Removes the bottom stack with buttons
if let stackButton = self.view.viewWithTag(50){
stackButton.removeFromSuperview()
}
//Add the button back with half ares size
bottomHolder.addSubview(rightButton)
rightButton.setImage(nil, for: .normal)
rightButton.addTarget(self, action: #selector(anima), for: .touchUpInside)
rightButton.topAnchor.constraint(equalTo: bottomHolder.topAnchor).isActive = true
rightButton.trailingAnchor.constraint(equalTo: bottomHolder.trailingAnchor).isActive = true
rightButton.bottomAnchor.constraint(equalTo: bottomHolder.bottomAnchor).isActive = true
}
#objc func anima(){
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.rightButton.leadingAnchor.constraint(equalTo: self.bottomHolder.leadingAnchor).isActive = true
self.rightButton.layoutIfNeeded()
}, completion: nil)
}
Irrelevant code below
try this one:
let buttonFinalWidth = UIScreen.main.bounds.width
DispatchQueue.main.async {
UIView.animate(withDuration: 5.0) {
self.rightButton.widthAnchor.constraint(equalToConstant: buttonFinalWidth).isActive = true
self.view.layoutIfNeeded()
}
}

Swift UIImage Animation - Fly in from outside of frame into frame

I am currently trying to see if there are any tutorials or some reference on how to animate UIImages to fly in from outside of frame into frame. I am currently trying to use the bottom code but it isn't producing what I would like.
I am creating a DC Universe intro page where the main characters will fly in one at a time and form a nice collection of characters which I think would be really cool.
UIView.animate(withDuration: 0.5, animations: {
self.superManImage.frame.origin.x -= 200 }, completion: nil)
This so far is working for me. Batman image flys in from top and Superman image flys in from left.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
superManImage.center.x -= view.bounds.width
batManImage.center.y -= view.bounds.width
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 0.8, delay: 1.0, options: [], animations: {
self.superManImage.center.x += self.view.bounds.width
}, completion: nil)
UIView.animate(withDuration: 0.5, delay: 0.3, options: [], animations: {
self.batManImage.center.y += self.view.bounds.width
}, completion: nil)
}

Strange animation 'lag' after launch screen disappears and before viewDidAppear() method runs

After launch screen dismisses itself logo and title of my app (they are in container) should go closer to the top of the screen. Between dismissing launch screen and viewDidAppear method there is a strange 'blink' of my container in the background. As you can see I am using snapkit but it should have nothing to do with the problem. Here is my code:
class WelcomeScreenViewController: UIViewController {
var welcomeScreenView: WelcomeScreenView {
return view as! WelcomeScreenView
}
override func loadView() {
let contentView = WelcomeScreenView(frame: .zero)
view = contentView
}
override func viewDidLoad() {
super.viewDidLoad()
self.welcomeScreenView.checkWeatherButton.transform = CGAffineTransform(translationX: 0, y: 200)
self.welcomeScreenView.checkWeatherButton.addTarget(self, action: #selector(showCityChoiceVC), for: .touchUpInside)
navigationController?.isNavigationBarHidden = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.welcomeScreenView.appNameLogoContainerVerticalConstraint?.isActive = false
self.welcomeScreenView.appNameLogoContainer.snp.makeConstraints({ (make) in
make.top.equalTo(self.welcomeScreenView).offset(100)
})
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: [], animations: {
self.welcomeScreenView.layoutIfNeeded()
self.welcomeScreenView.checkWeatherButton.transform = CGAffineTransform(translationX: 0, y: 0)
}, completion: nil)
}
#objc private func showCityChoiceVC() {
self.navigationController?.pushViewController(RegisterViewController(), animated: true)
}
Blinking comes from setting constraints in viewDidAppear. Use viewWillAppear or viewDidLoad instead. viewDidAppear is invoked when your view actually appears on screen. So any changes that happen will be visible to the user.

Custom Slide Segue - Xcode 8.0 Swift 3.0

What is the best way to create a custom segue that lets me press a button and then a view controller slides on. I have created a left to right segue but I want to make it go the other way. I have looked at some Youtube videos and this question but they don't show me what I want.
My code:
import UIKit
class SegueFromLeft: UIStoryboardSegue
{
override func perform()
{
let src = self.sourceViewController
let dst = self.destinationViewController
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransformMakeTranslation(-src.view.frame.size.width, 0)
UIView.animateWithDuration(0.25,
delay: 0.0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: {
dst.view.transform = CGAffineTransformMakeTranslation(0, 0)
},
completion: { finished in
src.presentViewController(dst, animated: false, completion: nil)
}
)
}
}
Basically, I want to create a segue that goes from right to left.
Thanks
I am using Xcode 8.0 and Swift 3.0
Try this:
class SegueFromLeft: UIStoryboardSegue{
override func perform(){
let src=sourceViewController
let dst=destinationViewController
let slide_view=destinationViewController.view
src.view.addSubview(slide_view)
slide_view.transform=CGAffineTransform.init(translationX: src.view.frame.size.width, 0)
UIView.animateWithDuration(0.25,
delay: 0.0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: {
slide_view.transform=CGAffineTransform.identity
}, completion: {finished in
src.present(dst, animated: false, completion: nil)
slide_view.removeFromSuperview()
})
}
}
Swift 3.1:
class ProceedToAppStoryboardSegue: UIStoryboardSegue {
override func perform(){
let slideView = destination.view
source.view.addSubview(slideView!)
slideView?.transform = CGAffineTransform(translationX: source.view.frame.size.width, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseInOut,
animations: {
slideView?.transform = CGAffineTransform.identity
}, completion: { finished in
self.source.present(self.destination, animated: false, completion: nil)
slideView?.removeFromSuperview()
})
}
}