I investigated but I could not find anything like this for Swift. Can you please help me make this animation in Swift?
Val animador = ValueAnimator.ofFloat(0.0f ,1.0f)
animador.repeatCount = ValueAnimator.INFINITE
animador.interpolator= LinearInterpolator()
animador.duration = 10000L
animador.addUpdateListener { animation ->
val progreso = animador.animatedValue as Float
Val anchura = fondo!!.width
fondo!!.traslationx = transicionX
fondo2!!.traslationx = transicion X -anchura
}
animador.start()
This may not be exactly right, but try this:
let anchura = fondo.frame.width
UIView.animate(withDuration: 1, delay: 0, options: [.repeat, .autoreverse], animations: {
fondo.frame.origin.x = CGFloat(transicionX)
fondo2.frame.origin.x = CGFloat(transicionX) - anchura
})
Swift animations start automatically (no need to start() or anything).
Edit:
Inside the animations block, you just put the final value that you want. This means that you don't need to calculate the progress or anything, and you probably don't even need a transicionX variable. Instead, try this:
let anchura = fondo.frame.width /// let's say this is 50
UIView.animate(withDuration: 1, delay: 0, options: [.repeat, .autoreverse], animations: {
fondo.frame.origin.x += anchura /// move fondo to the right by 50
fondo2.frame.origin.x -= anchura /// move fondo2 to the left by 50
})
Another edit: made it += and -= to animate on top of existing values
Related
I have to make a target appear and disappear randomly, e.g. in a space of 20 seconds but want to fix the flash first. The object is inserted programmatically and is just a png with collision. When the ball hits it, it disappears and the score is added. This part already works. Current code below
Spawn the enemy(is part of the function for the other 4 enemies)
let enemy1 = UIImageView(image: nil)
enemy1.image = UIImage(named: "enemy2.png")
enemy1.frame = CGRect(x: w*0.85, y: h*0.035, width: w*0.12, height: h*0.22)
self.view.addSubview(enemy1)
Add 1 to score when hit:
collisionBehaviour = UICollisionBehavior(items:[enemy1])
dynamicAnimator.addBehavior(collisionBehaviour)
collisionBehaviour.action = {
for boulderView in self.bouldersArray{
if boulderView.frame.intersects(enemy1.frame){
//enemy1.removeFromSuperview()
if enemy1.superview != nil{
self.scoreCount += 1
self.scoreCountLabel.text = "Score: \(self.scoreCount)"
enemy1.removeFromSuperview()
}
}
}
}
It's very hardcoded, please don't fix that. Tried an if statement to make it appear and disappear from subview, but it didn't work at all, just failed madly.
To make it disappear, set the alpha property to 0
enemy1.alpha = 0
To make it appear, set the alpha property to 1
enemy1.alpha = 1
if you wish to animate the disappearing use UIView Animate method
UIView.animate(withDuration: 0.3, delay: 0.5, options: .curveEaseOut, animations: {
self.enemy1.alpha = 0
}, completion: nil)
I am new to coding in Swift. I am working with animations, and I have a problem.
UIView.animate(withDuration: TimeInterval(waitTime), delay: 0, options: [.allowUserInteraction, .allowAnimatedContent, .curveLinear, .repeat], animations: {
UIView.setAnimationRepeatCount(Float(self.clickAccuracy))
// Animate tiles going down
self.tileButton1.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton2.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton3.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton4.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton5.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
})
Here, I want to repeat an animation of a UIButton moving down. (I have to repeat the animation in smaller blocks because I want to be able to click on the moving button). However, the buttons are going down as far as they are meant to, but instead of repeating again from that position, it resets. This causes an infinite flicker.
All I need is for the buttons to move down, without the position restarting to its original position, so I can have a smooth animation. Thanks!
Here is a video
https://i.imgflip.com/27uzl3.gif
Turns out, the original way I did didn't seem to work. So I changed it to this:
var numberOfIterations = 0
func repeatAnimation() {
UIView.animate(withDuration: TimeInterval(waitTime), delay: 0, options: [.allowUserInteraction, .allowAnimatedContent, .curveLinear, .curveLinear], animations: {
//UIView.setAnimationRepeatCount(Float(self.clickAccuracy))
// Animate tiles going down
self.tileButton1.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton2.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton3.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton4.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
self.tileButton5.center.y += self.tileButtonExample.frame.height / CGFloat(self.clickAccuracy)
}, completion: { (Finished) in
numberOfIterations += 1
// Repeat
if numberOfIterations != self.clickAccuracy {
self.repeatAnimation()
}
})
}
When #rmaddy gave me this answer, we forgot to remove the setAnimationRepeatCount (commented out). To make this repeat a set number of times, I put an if statement in the completion block.
I also got rid of .repeat in the animation options.
Thanks for everyone's help!
I want to make a UIView, circle, that scale based on volume of speak recording. I have this code to obtain the rate:
recorder.updateMeters()
let ALPHA = 0.05
let peakPower = pow(10, (ALPHA * Double(recorder.peakPower(forChannel: 0))))
How can I make this animation? I I make only:
self.audioCircle.transform = CGAffineTransform(scaleX: 1+CGFloat(rate), y: 1+CGFloat(rate))
the animation is too static, I need a more natural bounce effect, how can I do?
thanks!
.transform is what's implicitly animating your views change in size.
In that case, you should try using:
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.75, initialSpringVelocity: 0, options: .curveEaseOut, animations: {
//update view
self.view.layoutIfNeeded()
}, completion: { (completed) in
//animation completed
})
The above animation might be what you want to use to animate your view. It gives a nice bounce effect, and you can play with the parameters to adjust it accordingly.
However, because of the nature of the input, I'm not sure how the animation will fare.
It might be best to update the audioCircle size every so often, as opposed to constantly. This would allow the animation time to preform both correctly and smoothly as opposed to rigidly.
Good luck.
I wanted to make some tests. I thought, let's make an animation for a cell in a UITableView such as: it goes from the normal size, expand horizontally a bit over the normal size, reduce horizontally a bit under the normal size and go back to the normal size. So I thought make this:
let width = cell.frame.size.width
cell.frame = CGRectMake(0, cell.frame.origin.y, width, cell.frame.size.height)
UIView.animateWithDuration(4.25, animations: {
cell.frame = CGRectMake(width * -1/8, cell.frame.origin.y, width * 5/4, cell.frame.size.height)
}, completion: { finished in
UIView.animateWithDuration(2.5, animations: {
cell.frame = CGRectMake(width * 1/8, cell.frame.origin.y, width * 3/4, cell.frame.size.height)
}, completion: { finished in
UIView.animateWithDuration(1.25) {
cell.frame = CGRectMake(0, cell.frame.origin.y, width, cell.frame.size.height)
}
})
})
Use animations and completions in cascades. The problem is at the beginning. The frame reduces quickly horizontally (instead of expanding) then slowly (4.25 seconds) expands to the normal size. Then it reduces and then expand back to normal as expected.
Am I doing something wrong?
I was actually fiddling with animations just like the one you were doing just now :)
You can do the horizontal effect much easier; Instead of redefining the frame itself, you can simply adjust the horizontal bounds of the cell:
cell.bounds.size.width += 30 //grow it horizontally by 30 points
There's also a much more succinct method in dealing with this problem: UIView.animateKeyframesWithDuration(_ delay: options: animations: completion:)
With animateKeyframes, you can string a list of different animation effects in order, which is what you want. I'll start you off:
UIView.animateKeyframesWithDuration(4.0, delay: 0.0, options: nil, animations: {
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.25, animations: {
self.cell.bounds.size.width += 30
})
UIView.addKeyframeWithRelativeStartTime(2.5, relativeDuration: 0.1, animations: {
self.cell.bounds.size.width -= 60
})
UIView.addKeyframeWithRelativeStartTime(3.0, relativeDuration: 0.1, animations: {
self.cell.bounds.size.width += 30
})
}, completion: nil)
To put it simply, you define a duration for which the animation will occur. For the above code sample, I've defined 4 seconds.
Within the 4 seconds, I defined 3 different animations, specifying at what time they should fire off, and how long they should be fired for (relativeDuration, which is relative to the 4.0 second value).
Adjusting those numbers will allow you to customize the timings.
Hope that works!
I am using the library AutoScrollLabel for autoScrollLabel like marquee and its working perfect when I need the label to scroll from left to right.
But when I have to use the direction from right to left I have facing this problem:
the label begin from the last word to the first?
Why?
You can find below my code:
self.autoScrollLabel.textColor = [UIColor whiteColor];
self.autoScrollLabel.labelSpacing = 1; // distance between start and end labels
self.autoScrollLabel.pauseInterval = 0;
self.autoScrollLabel.scrollSpeed = 70; // pixels per second
self.autoScrollLabel.textAlignment = NSTextAlignmentCenter;
self.autoScrollLabel.fadeLength = 0;
self.autoScrollLabel.scrollDirection = CBAutoScrollDirectionRight;
self.autoScrollLabel.text = [NSString stringWithFormat:#"%#%#",#"",#"hello hello1 hello1 heeloo3 hello3 hebe hehehe hgdghdhg he e e hehee hehee hehehehehehhe"];
I've never used AutoScrollLabel class, but I think in order to it worked properly you should change property
self.autoScrollLabel.scrollDirection = CBAutoScrollDirectionLeft
when you scroll to the left
for Swift you you can call this method :
func startMarqueeLabelAnimation() {
DispatchQueue.main.async(execute: {
UIView.animate(withDuration: 20.0, delay: 1, options: ([.curveLinear, .repeat]), animations: {() -> Void in
self.marqueeLabel.center = CGPoint(x: 0 - self.marqueeLabel.bounds.size.width / 2, y: self.marqueeLabel.center.y)
}, completion: nil)
})
}