Showing error while using 'animateWithDuration' - swift

I am new in Swift so could not figure out the problem , Please guide me
using It like
UIView.animateWithDuration(duration, delay: 0.0, options: option, animations: { () -> Void in
self.btnCallButton.hidden = true
}, completion: nil)
and it showing following error
Cannot invoke 'animateWithDuration' with an argument list of type '(Float, delay: FloatLiteralConvertible, options: UIViewAnimationOptions, animations: () -> Void, completion: NilLiteralConvertible)'
please give the required suggestion and also provide some links which describe the blocks in swift

Like this:
UIView.animate(withDuration: 0.35) {
// animate things
return
}

Add return at end of closure as
UIView.animate(withDuration: duration, delay: 0.0, options: option, animations: { () -> Void in
self.btnCallButton.hidden = true
return
}, completion: nil)

Hidden is not animatable in Swift. If you want to hide/show via fade in/out use the following code for fadeout
UIView.animate(withDuration: duration, delay: 0.0, options: options, animations: {
self.btnCallButton.isHidden = false
self.btnCallButton.alpha = 0.0
}, completion: { finished in
self.btnCallButton.isHidden = true
})
and following for fadein
UIView.animate(withDuration: duration, delay: 0.0, options: options, animations: {
self.btnCallButton.isHidden = false
self.btnCallButton.alpha = 1.0
}, completion: { finished in
})

Related

UIProgressView not animating progress on iOS 13

I am not seeing the animation of a UIProgressView with Xcode 11.0/Swift 5/iOS 13:
private let timerProgressView: UIProgressView = {
let timerProgressView = UIProgressView()
timerProgressView.progressTintColor = white
timerProgressView.trackTintColor = .black
timerProgressView.setProgress(1.0, animated: false)
return timerProgressView
}()
private func triggerProgressView() {
UIView.animate(withDuration: viewModel.timeLimit, delay: 0.0, options: .curveLinear, animations: { [weak self] in
self?.timerProgressView.setProgress(0.0, animated: true)
}, completion: nil)
}
This code works on iOS <12 but not on iOS 13. Am I missing something?
we've faced it too and after about an hour of hair pulling we came up with a workaround, it looks like that is a bug. it ridiculous, but setting the progress to 0.0001 instead of 0.0 will do the job.
progressView.progress = 0.0001
UIView.animate(withDuration: duration,
delay: 0.0, options: [.curveLinear, .beginFromCurrentState, .preferredFramesPerSecond60],
animations: { progressView.layoutIfNeeded() },
completion: nil)
Did you try doing something like this? :
self?.timerProgressView.setProgress(0.0)
UIView.animate(withDuration: viewModel.timeLimit, delay: 0.0, options: .curveLinear, animations: { [weak self] in
self?.timerProgressView.layoutIfNeeded()
}, completion: nil)

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

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.

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
...
}

Smooth move of the contentoffset UIScrollView Swift

I would like to set the contentOffset of my scrollview programmatically when the contentOffset is between two points (please see the picture below) with Swift.
The problem is, I would like to add a smooth transition for the move, but I didn't find documentation for this. I tried to do a loop in order to decrease gradually the content offset but the result is not so good.
With this example, if the content offset is less than 150 px at the end of the scroll, it goes smoothly (duration of the animation would be 1 sec) to the point with the offset equal to 100. Up to 150 px, it goes to 200px.
If you can provide me directions (documentation or quick example) of what to do it would be great :) Thank you !
You can use UIView.animations
func goToPoint() {
dispatch_async(dispatch_get_main_queue()) {
UIView.animateWithDuration(2, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: {
self.scrollView.contentOffset.x = 200
}, completion: nil)
}
}
Swift version
DispatchQueue.main.async {
UIView.animate(withDuration: 0.2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
self.myScrollView.contentOffset.x = CGFloat(startingPointForView)
}, completion: nil)
}
Swift 4
DispatchQueue.main.async {
UIView.animate(withDuration: 1, delay: 0, options: UIView.AnimationOptions.curveLinear, animations: {
self.scrollView.contentOffset.x = 200
}, completion: nil)
}
Here is the Swift 3 version of fatihyildizhan's code.
DispatchQueue.main.async {
UIView.animate(withDuration: 0.2, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
self.myScrollView.contentOffset.x = CGFloat(startingPointForView)
}, completion: nil)
}
Now you can simply call the method setContentOffset(_ contentOffset: CGPoint, animated: Bool) instead of the previous workarounds calling a messy animation block. See:
x = CGFloat(startingPointForView)
myScrollView.setContentOffset(CGPoint(x: x, y: 0), animated: true)
Hope it helps.
Swift 4:
DispatchQueue.main.async {
UIView.animate(withDuration: 1, delay: 0, options: UIView.AnimationOptions.curveLinear, animations: {
self.scrollView.contentOffset.x = 200
}, completion: nil)
}

Whats the Swift animate WithDuration syntax?

I'm porting an older app over to Xcode 7 beta and I'm getting an error on my animations:
Cannot invoke 'animateWithDuration' with an argument list of type
'(Double, delay: Double, options: nil, animations: () -> _,
completion: nil)'
Here's the code:
UIView.animateWithDuration(0.5, delay: 0.3, options: nil, animations: {
self.username.center.x += self.view.bounds.width
}, completion: nil)
This works in Xcode 6 so I'm assuming this is an update in Swift. So my question is:
What's the Swift 3 syntax for animateWithDuration?
Swift 3/4 Syntax
Here's an update with the Swift 3 Syntax:
UIView.animate(withDuration: 0.5, delay: 0.3, options: [.repeat, .curveEaseOut, .autoreverse], animations: {
self.username.center.x += self.view.bounds.width
}, completion: nil)
If you need to add a completion handler just add a closure like so:
UIView.animate(withDuration: 0.5, delay: 0.3, options: [.repeat, .curveEaseOut, .autoreverse], animations: {
// animation stuff
}, completion: { _ in
// do stuff once animation is complete
})
Old Answer:
It turns out it's a very simple fix, just change options: nil to options: [].
Swift 2.2 Syntax:
UIView.animateWithDuration(0.5, delay: 0.3, options: [], animations: {
self.username.center.x += self.view.bounds.width
}, completion: nil)
What changed?
Swift 2 got rid of the C-Style comma-delimited list of options in favor of option sets (see: OptionSetType). In my original question, I passed in nil for my options, which was valid prior to Swift 2. With the updated syntax, we now see an empty option list as an empty set: [].
An example of animateWithDuration with some options would be this:
UIView.animateWithDuration(0.5, delay: 0.3, options: [.Repeat, .CurveEaseOut, .Autoreverse], animations: {
self.username.center.x += self.view.bounds.width
}, completion: nil)
Swift 3, 4, 5
UIView.animate(withDuration: 1.5, delay: 0.05 * Double(index), usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {
cell.transform = CGAffineTransform(translationX: 0, y: 0)
}, completion: nil)
Swift 3 Syntax with completion block
UIView.animate(withDuration: 3.0 , delay: 0.25, options: .curveEaseOut, animations: {
// animation
}, completion: { _ in
// completion
})
Swift 2
UIView.animateWithDuration(1.0, delay: 0.1, options: [.Repeat, .CurveEaseOut, .Autoreverse], animations: {
// animation
}, completion: { finished in
// completion
})
Swift 3, 4, 5
UIView.animate(withDuration: 1.0, delay: 0.1, options: [.repeat, .curveEaseOut, .autoreverse], animations: {
// animation
}, completion: { finished in
// completion
})