SetBackgroundImage prevents animation to run properly - ios

For some reason my animation does not run properly when I change the background of my button. I am new to animations was trying something new. I don't really need to change the background but it was how I had it in sketch and in my opinion it looks better when it is changed.
Code:
#IBAction func didTapWithUsername(sender: AnyObject)
{
// When this button is tapped the two buttons below should move down far enough to reveal
// two labels and two textboxes
// choose animation
if(userBtnTapped == 0)
{
tappedwithUserAnimationForSeperate()
userBtnTapped = 1
self.withUserNameBtn.setBackgroundImage(UIImage(named: "loginUserbtnWithFill.png"), forState: UIControlState.Normal)
}
else
{
tappedwithUserAnimationForClose()
userBtnTapped = 0
self.withUserNameBtn.setBackgroundImage(UIImage(named: "LoginWithUserbtn.png"), forState: UIControlState.Normal)
}
}
animation functions:
func tappedwithUserAnimationForSeperate()
{
UIView.animateWithDuration(1.0, delay: 0, usingSpringWithDamping: 1.0, initialSpringVelocity: 5.0, options: [], animations: ({
// code for animation goes here here
self.withUserNameBtn.center.y = self.withUserNameBtn.center.y - 60
self.withFBbtn.center.y = self.withFBbtn.center.y + 60
self.signUpBtn.center.y = self.signUpBtn.center.y + 60
}), completion: nil)
}
func tappedwithUserAnimationForClose()
{
UIView.animateWithDuration(1.0, delay: 0, usingSpringWithDamping: 1.0, initialSpringVelocity: 5.0, options: [], animations: ({
// code for animation goes here here
self.withUserNameBtn.center.y = self.withUserNameBtn.center.y + 60
self.withFBbtn.center.y = self.withFBbtn.center.y - 60
self.signUpBtn.center.y = self.signUpBtn.center.y - 60
}), completion: nil)
}

Related

How to Animate a UIView n number of times within a loop and track each animation event

UIView.animate(withDuration: 3.0, animations: {
// UIView.setAnimationRepeatCount(3.0)
self.leadng.constant = self.view.frame.size.width + self.vwObj.frame.size.width
self.view.layoutIfNeeded()
}, completion: { finished in
UIView.animate(withDuration: 3.0, animations: {
self.leadng.constant = -(self.vwObj.frame.size.width)
})
})
This is the code i am using for animating a UIView. What i am trying to do is to animate the UIView n number of times. That can be done using UIView.setAnimationRepeatCount(3.0), but the problem is i am having an array of different images which i want to show within the UiView for each animation. Anyone having any idea about how to do that
Use the animatedImage property of UIImage to animate multiple images inside a imageview.
ImageView.image = UIImage.animatedImage(with: myImages, duration: 1.0)
where myImages is array of images you want to animate.
Follow this link for details.
Edit: Definitely a very crude way, but it works.
Declared this at top of class.
let arrayColors = [UIColor.red , UIColor.green, UIColor.blue]
var animationCount = 0
I called animateView() in viewdidload
func animateView() {
self.vwObj.backgroundColor = arrayColors[animationCount]
UIView.animate(withDuration: 3.0, animations: {
self.leadng.constant = self.view.frame.size.width + self.vwObj.frame.size.width
self.view.layoutIfNeeded()
}, completion: { finished in
UIView.animate(withDuration: 3.0, animations: {
self.leadng.constant = 0
self.view.layoutIfNeeded()
}, completion: { finished in
self.animationCount = self.animationCount + 1
if self.animationCount < 3 {
self.animateView()
}
})
})
}
Insted of array of colors, you can use array of images to set imageview.image = arrayImage[animationCount]
Seems solved by the below code:
UIView.animate(withDuration: 3.0, animations: {
print ("Animation Started")
self.leadng.constant = self.view.frame.size.width + self.vwObj.frame.size.width
self.view.layoutIfNeeded()
print ("BeginCounter --- (self.counter)")
}, completion: { finished in
UIView.animate(withDuration: 3.5, animations: {
self.leadng.constant = -(self.vwObj.frame.size.width)
print ("AnimationCompleted")
self.counter = self.counter + 1
print ("CompleteCounter --- \(self.counter)")
//self.displayAnimation()
if (self.counter == 3) {
self.timer?.invalidate()
self.counter = 0
}
})
})
& calling---- timer = Timer.scheduledTimer(timeInterval: 4.0, target: self, selector: #selector(ViewController.displayAnimation), userInfo: nil, repeats: true)

How to do a sequence animation on a textview (swift3)

My code below is a button that when hit applies animation. Right now there are two animations. I would like to do a sequence the animations meaning have the 2nd animation not start until the first animation has completed.
var speed: CGFloat = 5.3 // speed in seconds
#IBAction func press(_ sender: Any) {
self.theTextView.resignFirstResponder()
UIView.animate(withDuration: TimeInterval(speed), animations: {
////1st action[
self.theTextView.contentOffset = .zero
self.theTextView.setContentOffset(.zero, animated: true)]
/////2nd action[
self.theTextView.contentOffset = CGPoint(x: 0, y: self.theTextView.contentSize.height)]
}, completion: nil)
}}
The easiest way of doing that would be using the completion block of the animate(withDuration:animations:completion:) method. The completion block is executed when the animation sequence ends. In your case, it would look like this :
UIView.animate(withDuration: 6.0, animations: {
// First animation goes here
self.theTextView.contentOffset = CGPoint.zero
}, completion: { (finished) in
// This completion block is called when the first animation is done.
// Make sure the animation was not interrupted/cancelled :
guard finished else {
return
}
UIView.animate(withDuration: 1.0, animations: {
// And the second animation goes here
self.theTextView.contentOffset = CGPoint(x: 0, y: self.theTextView.contentSize.height)
})
})
There is also convenient way to make sequence of concurrent animations by using animateKeyframes:
UIView.animateKeyframes(withDuration: 1, delay: 0, options: .calculationModeCubic, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.3, animations: {
self.someView.alpha = 0.5
self.view.layoutIfNeeded()
})
//second animation
UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.3, animations: {
self.someView.alpha = 1
self.view.layoutIfNeeded()
})
}, completion: { (finish) in
// Do something on animation complete
})

(Swift) Fade-In and Out a Label [duplicate]

This question already has answers here:
UIView Hide/Show with animation
(22 answers)
Closed 6 years ago.
I'm trying to fade a label in and out when it appears on the screen. Currently, I'm simply hiding it using
button.hidden = true
and unhiding it by using false. I would like to animate this process with a fade-in and out as it looks much smoother this way. Appreciate the help !
Here is the code I'm using which gets an error. http://imgur.com/a/HI4eg
class ViewController: UIViewController {
#IBOutlet weak var yeah: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseOut, animations: {
self.yeah.alpha = 0.0
}, completion: {
(finished: Bool) -> Void in
//Once the label is completely invisible, set the text and fade it back in
self.yeah.text = "your Text "
// Fade in
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseIn, animations: {
self.yeah.alpha = 1.0
}, completion: {
(finished: Bool) -> Void in
//Once the label is completely invisible, set the text and fade it back in
self.yeah.text = "your Text "
// Fade in
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseIn, animations: {
self.yeah.alpha = 1.0
}, completion:nil )
})
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
}
As explained in andrew bancroft's blog
// Move our fade out code from earlier
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseOut, animations: {
self.yourLabel.alpha = 0.0
}, completion: {
finished in
if finished {
//Once the label is completely invisible, set the text and fade it back in
self.yourLabel.text = "your Text "
// Fade in
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseIn, animations: {
self.yourLabel.alpha = 1.0
}, completion: nil)
}
})
Modified Answer
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseOut, animations: {
self.yourLabel.alpha = 0.0
}, completion: {
finished in
if finished {
//Once the label is completely invisible, set the text and fade it back in
self.yourLabel.text = "your Text "
// Fade in
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseIn, animations: {
self.yourLabel.alpha = 1.0
}, completion: {
finished in
if finished {
//Once the label is completely invisible, set the text and fade it back in
self.yourLabel.text = "your Text "
// Fade in
UIView.animateWithDuration(1.0, delay: 0.0, options: .CurveEaseIn, animations: {
self.yourLabel.alpha = 0.0
}, completion: nil)
}
})
}
})

iOS Label Visibility toggle not animating

I am trying to toggle the visibility of a UILabel based on a Tap Gesture on an UIImageView. The code that performs the toggling is as follows:
func imageTapped(img: UIImageView) {
print(photoTitle.hidden)
if (photoTitle.hidden) {
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
self.photoTitle.alpha = 1
}, completion: nil)
}
else {
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
self.photoTitle.alpha = 0
}, completion: nil)
}
self.photoTitle.hidden = !self.photoTitle.hidden
}
The issue with this is that it seems to ignore the animation on the second tap i.e. to hide the UILabel again. It just becomes invisible instead of animating gradually. In the viewdDidLoad(), I initialize the photoTitle.hidden = true to be invisible initially.
Any glaring mistakes?
You need to move self.photoTitle.hidden = true into the completion block of your else condition
hidden doesn't work on this animation, you can instead of alpha
Just try to change the function like this
Swift 2
func imageTapped(img: UIImageView) {
print(photoTitle.hidden)
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
self.photoTitle.alpha = self.photoTitle.alpha < 0.5 ? 1.0 : 0.0
}, completion: nil)
}
Swift 3, 4, 5
func imageTapped(img: UIImageView) {
print(photoTitle.hidden)
UIView.animate(withDuration: 0.5, delay: 0, options: UIView.AnimationOptions.curveEaseInOut, animations: {
self.photoTitle.alpha = self.photoTitle.alpha < 0.5 ? 1.0 : 0.0
}, completion: nil)
}

Incrementing a parameter in UIView.animateWithDuration in Swift

I have an IBOutlet Collection of buttons that I am trying to present on screen sequentially. They all start off screen fine, but as they animate in, I'd like each button to be presented on screen 0.05 seconds after the previous button. I can't figure out how to increment the delay in UIView.animateWithDuration. With the code below, they are all animating on screen at the same time.
//outlet collection
#IBOutlet var options: [UIButton]!
let increment = 0.25
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
for button in options {
button.center.y += view.bounds.height
}
}
override func viewDidLoad() {
super.viewDidLoad()
for button in options {
UIView.animateWithDuration(1.0, delay: increment, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: nil, animations: {
button.center.y -= self.view.bounds.height
self.increment + 0.05
}, completion: nil)
}
}
for button in options {
UIView.animateWithDuration(1.0, delay: increment, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: nil, animations: {
button.center.y -= self.view.bounds.height
}, completion: nil)
}
increment = increment + 0.05
}
Besides:
Change this
let increment = 0.25
To
var increment = 0.25
Increase the increment outside animation. Because animateWithDuration is an async method,it will return first. So,all your button have same delay.
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet var options: [UIButton]!
let increment = 0.25
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
for button in options {
button.center.y += view.bounds.height
}
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
for button in options {
UIView.animateWithDuration(1.0, delay: increment, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: nil, animations: {
button.center.y -= self.view.bounds.height
}, completion: nil)
self.increment + 0.05
}
}
Also getting error "Cannot invoke '+=' with an argument list of type '(Double, FloatLiteralConvertible)'" when using += but it will take just +
Here is the way to achieve the required delay between animations:
var i! as UInt64;
i = 0
for button in options {
// your animation with delay
UIView.animateWithDuration(1.0, delay: (i *0.05), usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: nil, animations: {
button.center.y -= self.view.bounds.height
}, completion: nil)
})
++i
}

Resources