Fade in chain animations don't work: only view fades in - swift

I'm trying to use a fade in animation chain to fade in my objects in order. First I make the view fade in, then the rest of the labels should follow suit. The labels are in a stack view, which has an alpha of 1.0. I made sure that all of the other alpha values started at zero. Here is my function:
func fadeIn() {
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.view.alpha = 1.0
}, completion: { finished in
if finished {
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.gameOverLabel.alpha = 1.0
}, completion: { finished in
if finished {
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.scoreLabel.alpha = 1.0
}, completion: { finished in
if finished {
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.highScoreLabel.alpha = 1.0
}, completion: { finished in
if finished {
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIView.AnimationOptions.curveEaseIn, animations: {
self.restartButton.alpha = 1.0
}, completion: nil)
//breakpoint set here
}
})
}
})
}
})
}
})
}
I set a breakpoint after all of the animations were completed(as shown above) and all alpha values were 1.0. However, the device just gives me a blank, white screen. What is going on?
P.S. The function is called immediately after this view controller is presented:
view.present(vc, animated: false, completion: {
vc.fadeIn()
})

Try adding the .layoutSubviews option to your animations. Like this:
UIView.animate(withDuration: 1.0, delay: 0.0, options: UIView.AnimationOptions.layoutSubviews, animations: {
// animate here
})
From apple's docs this option does this:
Lay out subviews at commit time so that they are animated along with their parent.
Might be that the subviews aren't laid out yet at commit time due to being presented.

Related

UIView animations with scale and alpha

I need make animation to show/hide view (UIButton), so alpha changes from 0 to 1 same time as scale of view changes from 0 to 100% (showing) and reverse (hiding). Each animation I can do separately but how make it together? And It must showing/hiding correct when user randomly (and may be so fast, for example, hiding animation not finished - showing animation starts) interact. Any help will be appreciated.
continuing the previous comments, I try to make a simple example.
so maybe the trick is in the transform "identity" which functions to restore the view to its origin, hopefully it helps
#IBAction func showButtonTapped(_ sender: Any) {
UIView.animate(withDuration: 1.0, delay: 0.5, usingSpringWithDamping: 0.6, initialSpringVelocity: 1, options: [.curveEaseIn], animations: {
self.yourView.transform = .identity
self.yourView.alpha = 1
}, completion: nil)
}
#IBAction func hideButtonTapped(_ sender: Any) {
UIView.animate(withDuration: 1.0, delay: 0.5, usingSpringWithDamping: 0.6, initialSpringVelocity: 1, options: [.curveEaseOut], animations: {
self.yourView.transform = CGAffineTransform.identity.scaledBy(x: 0.7, y: 0.7)
self.yourView.alpha = 0
})
}

UIButton animation ignores target selector in Swift

I've added this animation code to the end of a function that is called when the button is pushed, but while the animation is happening, it ignores the set target selector until the animation is finished. The animation is very fast, but I'd like users to be able to press it rapidly.
let transforms: CGAffineTransform = .identity
mirroredButton.transform = transforms
UIView.animate(withDuration: 0.05, animations: {
mirroredButton.transform = transforms.scaledBy(x: 0.75, y: 0.75)
},
completion: { _ in
UIView.animate(withDuration: 0.1) {
mirroredButton.transform = transforms.scaledBy(x: 1.0, y: 1.0)
}
})
Update:
Using the answer, I updated my animation code as shown below. Both animation calls need options. The 2nd has a nil completion handler.
let transforms: CGAffineTransform = .identity
mirroredButton.transform = transforms
UIView.animate(withDuration: 0.05, delay: 0.0, options: .allowUserInteraction, animations: {
mirroredButton.transform = transforms.scaledBy(x: 0.75, y: 0.75)
},
completion: { _ in
UIView.animate(withDuration: 0.1, delay: 0.0, options: .allowUserInteraction, animations: {
mirroredButton.transform = transforms.scaledBy(x: 1.0, y: 1.0)
}, completion:nil)
})
User interaction is disabled for the duration of a view's animation. If it's critical that the user should interact with a view during an animation, you can pass in the option .allowUserInteraction, like so:
UIView.animate(withDuration: 1.0, delay: 0.0, options: .allowUserInteraction, animations: {
//animate here
})

i am trying to animate my unbutton with a constraint and the animation is not working

Can some one please tell me why this is not animating? I feel that the code is all perfect but the animate function is not working. The button is jumping instantly from side to side but like i said it isn't animating...
func moveResetButton( constraint : NSLayoutConstraint, isOffScreen : Bool) {
if isOffScreen {
//animate the button onto the screen
UIView.animate(withDuration: 3.0, delay: 0.0, options: .curveLinear, animations: {
constraint.constant += 120
}, completion: nil)
} else {
//animate the button off of the screen
UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveLinear, animations: {
constraint.constant -= 120
}, completion: nil)
}
}
i figured it out. just need to add self.view.layoutIfNeeded() to the code under the constraint change. worked smoothly.

viewDidAppear() running on every click

I am trying to create an animation slide in for two textfields and a label. However for some reason the viewDidAppear() function runs every time you attempt to click the textfield, causing them to continue to animate. Does anyone have any ideas?
This is my code for the function:
override func viewDidAppear(animated: Bool)
{
//Some Code here
UIView.animateWithDuration(1.5, delay: 0.5,
usingSpringWithDamping: 0.3,
initialSpringVelocity: 0.5,
options: [], animations: {
self.Email.center.x += 475
self.Password.center.x -= 400
}, completion: nil)
UIView.animateWithDuration(2.0, delay: 2.0,
options: [],
animations: {
self.LoginButton.alpha = 1.0
}, completion: nil)
UIView.animateWithDuration(1.5, delay: 0.5,
usingSpringWithDamping: 0.3,
initialSpringVelocity: 0.5,
options: [], animations: {
self.LoginL.center.y += 100
}, completion: nil)
}
As we found out the problem was with the UIViewController's life cycle - it was needed to call super.viewDidAppear(animated).
try to run it viewWillAppear instead, your animation will be run only when your screen loads for the first time.

UIViewAnimationOptions.CurveEaseIn not working inside coordinated animation

I am in the middle of developing a tvOS application.
In my application I have a UICollectionView. On focus I am using a coordinated animation. Inside that animation I have this code:
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.bg.image = finalImage
self.bg.alpha = 1.0
}, completion: nil)
But it seems like its not using the curveEaseIn animation option.
Its changing the alpha bluntly, which is odd. Where I am going wrong?
Sorry. Forgot to post the answer.
I did animating the imageview in the completion of the coordinated animation like this
self.bg.alpha = 0.0
coordinator.addCoordinatedAnimations({ //code for coordinated animation}, completion: { _ in
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.bg.image = self.finalImage
self.bg.alpha = 1.0
}, completion: nil)})
What is the desired effect? Are you trying to cross fade bg.image with a new image? Have you tried changing the duration to something higher, for example 10.0, to see if the animation is perhaps happening too fast?
Here's an example of what you may be looking for:
let myImageView = UIImageView()
let myFinalImage = UIImage(named:"FinalImage.png")
// Animate alpha
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseIn, animations: {
print("alpha animation started")
myImageView.alpha = 0.0
}) { (finished) in
print("alpha animation finished")
}
// Animate change of image
UIView.transitionWithView(myImageView, duration: 1.0, options: .TransitionCrossDissolve, animations: {
print("cross dissolve animation started")
myImageView.image = myFinalImage
}) { (finished) in
print("cross dissolve animation finished")
}
In Swift 4 or Swift 5 use: .curveEaseIn
UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveEaseIn, animations: {
...
}) { (finished) in
...
}