Swift animate UIButton background images - swift

I have a UIButton that shows an image. When the button is tapped I want to show a checkmark and then animate back to the original image. I've never worked with animation so hopefully, you can help. With the code below I do get 1 and 2 in my debug window, but the "1st" image doesn't show up or displays way too fast. I have played with all the value and can't seem to get the proper values. So basically, you tap the button, circle_150px_green filled copy shows (checkmark), what a short duration, and original button image out of country shows...
Thanks in advance.
UIView.animateKeyframes(withDuration: 25.0, delay: 0.0, animations: {
//add keyframes
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 10.0, animations: {
print("1")
sender.setImage(#imageLiteral(resourceName: "circle_150px_green filled copy"), for: .normal)
})
UIView.addKeyframe(withRelativeStartTime: 5.0, relativeDuration: 0.5) {
print("2")
sender.setImage(#imageLiteral(resourceName: "out of country"), for: .normal)
}
}, completion: nil)

Related

how to animate the a particular label from bottom to top in swift

I want to animate label from bottom to top.
I am using this code
UIView.animate(withDuration: 2, delay: 0, options: [.curveEaseOut],
animations: {
quoteLbl.center.y -= self.view.bounds.height - 100
self.view.layoutIfNeeded()
}, completion: nil)
but this code animate the whole view and I want to animate a particular label of UIViewController

UI Animation using animateKeyframes does nothing to Button Title Color

I'm trying to animate the color of my UIButton Title Color using animateKeyframes but it does nothing except load the last state in the animation, in this case purpleText. I'm using the same code to animate button colors and a UIView background color without any issues.
I checked also changed the button to a custom button in Interface Builder but that didn't help either.
UIView.animateKeyframes(withDuration: 12, delay: 12, options: [.allowUserInteraction, .repeat, .autoreverse], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.25, animations: {
self.infoButton.setTitleColor(blueText, for: UIControlState.normal)
})
UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.25, animations: {
self.infoButton.setTitleColor(greenText, for: UIControlState.normal)
})
UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.25, animations: {
self.infoButton.setTitleColor(yellowText, for: UIControlState.normal)
})
UIView.addKeyframe(withRelativeStartTime: 0.6, relativeDuration: 0.25, animations: {
self.infoButton.setTitleColor(redText, for: UIControlState.normal)
})
UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 0.25, animations: {
self.infoButton.setTitleColor(purpleText, for: UIControlState.normal)
})
}, completion: nil)
Calling setTitleColor() inside the animation block doesn't work because UIView.animate only works on animatable properties, like infoButton.backgroundColor.
Unfortunately, button properties like tintColor aren't animatable. You also shouldn't directly access the button's titleLabel, which is nil for system buttons.
Instead, you can use UIView.transition with setTitleColor(). You can then put it inside a Timer... I usually don't like to use timers for animations, but I can't think of any other way.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let colors: [UIColor] = [.blue, .green, .yellow, .red, .purple]
var currentIndex = 0
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
if colors.indices.contains(currentIndex) {
UIView.transition(with: self.infoButton, duration: 0.5, options: [.transitionCrossDissolve, .allowUserInteraction]) {
self.infoButton.setTitleColor(colors[currentIndex], for: .normal)
}
currentIndex += 1
} else {
currentIndex = 0
}
}
}
Result:

UICollectionViewCell Custom Animation On Tap

My goal is to build a custom cell that, when tapped, animates similar to Snapchat's. I have gotten the animation to work, but as a scroll more (after tap), the last selected cell continues to animate as I tap around the screen. Here's a video example
To get this animation, I am overriding the isSelected value in a custom cell class like so:
override var isSelected: Bool {
didSet {
if isSelected {
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: {
self.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
}, completion: { _ in
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: {
self.transform = CGAffineTransform(scaleX: 1, y: 1)
}, completion: nil)
})
}
}
}
Please help me figure out why the last selected cell continues to animate even after the correct animation is completed.

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()
}
}

UIButton transition

I have a group of six buttons - when one is pressed (programmatically) I would like it to light up and then fade out. So I created a function called lightUp(button: UIButton). I also have two images for each button - lit and unlit. I can go from the default unlit to lit, but so far, trying to light the button first, before fading it back to unlit has been a problem. In the code below, the buttons don't light up at all.
func lightUp(button: UIButton){
button.setImage(UIImage(named: padArrayOn[button.tag]), for: .normal)
UIView.transition(with: button, duration: 0.4, options: .transitionCrossDissolve, animations: {
button.setImage(UIImage(named: self.padArrayOff[button.tag]), for: .normal)
}) { (bool) in
self.playSequence()
}
}
Set two transitions, the second in the completion handler of the first perhaps?
func lightUp(button: UIButton){
UIView.transition(with: button, duration: 0.2, options: .transitionCrossDissolve, animations: {
button.setImage(UIImage(named: padArrayOn[button.tag]), for: .normal)
}, completion: {_ in
UIView.transition(with: button, duration: 0.2, options: .transitionCrossDissolve, animations: {
button.setImage(UIImage(named: self.padArrayOff[button.tag]), for: .normal)
}, completion: { _ in
self.playSequence()
}
)})
}
if I understood you correctly you want to light up the button (maybe change the background) and then it should fade out.
You can try something like this:
func lightUpAndFadeOut(button: UIButton){
UIView.animate(withDuration: 2) {
button.backgroundColor = UIColor.red
}
UIView.animate(withDuration: 5) {
button.alpha = 0
}
}
Every button calls this function and it should look like this:
lightUpAndFadeOut(button: sender as! UIButton)
Correct?