stop animateWithDuration in navigationItem - ios

i am trying to animate my navigationItem.rightBarButtonItem to blink repeatedly from green to white... So I do this
UIView.animateWithDuration(1.0, delay:0, options: [.Repeat, .Autoreverse], animations: {
self.navigationItem.rightBarButtonItem?.tintColor = .greenColor()
}, completion: nil)
as i see in this question
and it work
the problem is that i am using UITabView and every time i switch between views and return to the first view the blink is stop
and i think its because i stuck layer after layer of animation somewhere
i understand that to remove the animation i should use layer.removeAllAnimations()
the problem is that i don't know which view to do it on
i tried self.view.layer.removeAllAnimations()
and it didn't work.
how do i get to this layer that i create for the navigationItem animation
so i can remove it?

i solve this issue with relocating the creation of the animation
in the beginning i placed that in the viewWillAppear function
and also tried to init the button to white color just before that
but its looks like it didn't work that way so i relocate the animation to
the viewDidAppear function and leave the init of the button to white color
in the viewWillAppear and its seems to work ok now :)
thanks

Related

How to ensure UITableView header cell subview with repeating animation continues animating after a reloadData, user scroll, etc?

I have a ViewController with a header cell that is working well, except that one view in the header cell has a repeating animation that should continue animating endlessly when particular conditions are set in the view controller. I can start the animation sometimes successfully in viewDidLoad and restart it in my handler for the .appDidBecomeActive notification. However when the user scrolls or pulls to refresh the tableview data, the animation stops. I did override the scrollViewDidEndDragging & scrollViewDidEndDecelerating methods to restart it, but its not actually reliably restarting the animation. Clues?
UIView.animate(withDuration: 2.0,
delay: 0.0,
options: [.curveEaseInOut, .autoreverse, .repeat, .beginFromCurrentState],
animations: { self.headerCellAnimatedSubview?.alpha = 1.0 },
completion: { _ in self.headerCellAnimatedSubview?.alpha = 0.0 }
)
After some help I found that adding the animation call to the UITableViewHeaderCell class's override of didMoveToWindow the animation will restart after scroll. However as expected I also had to respond to the appDidBecomeActive notification to restart the animation when the app returns fro background.

When animating view with UIView.animate other views are also needlessly animated

I'm wondering why views in my custom TableViewCells are affected by animation which should animate only 2 views in my floating pager (which is even not in TableView's view hierarchy..
UIView.animate(withDuration: 0.3) {
self.stateIndicator.isHiddenInStackView = true
self.loaderIndicator.isHiddenInStackView = false
}
When I comment out animation block everything stops animating.
Attached GIF describes everything (Blue views gets animated corner radius, badges 'flies in' instead of just appearing):
UIView.animate strange behavior
Any help or hint will be appreciated :).
Regards Tom.
Write the things which you don't want to animate in the block
UIView.performWithoutAnimation {
//Write your code here
}
I make my animation in main queue and it worked.
For example
DispatchQueue.main.async {
//Write animation code here
}

First time animating is glitchy

I am animating a view gradientView in/out using the following:
func hideOrShowGradientView(hide: Bool) {
UIView.animate(withDuration: 0.4, animations: {
self.gradientView.isHidden = hide
})
}
This works well, but on the first time, there is no animation. It just appears. On the second and third time it works wonderfully. I've tried calling the animate block on the main thread but no luck there. Why is this animation failing to occur on the first and only first time around? Should I be using another animation method?
Have you tried calling self.view.layoutIfNeeded(). It forces the view and it's subviews to complete any of it's pending animations immediately, which might be interfering with your animation. You can use it like this:
func hideOrShowGradientView(hide: Bool) {
self.view.layoutIfNeeded()
UIView.animate(withDuration: 0.4, animations: {
self.gradientView.isHidden = hide
self.view.layoutIfNeeded()
})
}
Apple recommends calling layoutIfNeeded() twice, once before the animation block which forces a redraw on the view and it's subviews, and it completes any pending animations on the view without waiting for the next update cycle, and call it the second time inside the animation block to make sure that the animation changes will be applied immediately.
I had too much going on the main thread in the init method, which was being called only on the first time the view was being presented. Moved unnecessary initialization into view did appear

Animation doesnt work - Swift

Everytime I try to implement an animation in my viewDidLoad, it doesn't work. Any suggestions?
UIView.animate(withDuration: 2.0, delay: 0, options:
[.repeat,.autoreverse], animations: {
self.viewpost.transform = CGAffineTransform(rotationAngle: 360)
}, completion: nil)
Just move your animation to ViewDidAppear.
In ViewDidLoad the ViewController will load but is not shown yet. Because of that the animations wont show or may partially show if the animation is longer than the time for the View Controller to Appear after loading.
In ViewDidAppear the ViewController is on the screen so your animations will fully take place
Hope this helps!

How to recognize tap gesture while a view is animating

Just wondering is there way to have a view recognize tap gestures while it is being animated? I am working on a view that has a cashapelayer line tethered to it. When the user pans the view (pan gesture) the line follows accordingly until the user stops panning. At this point an animation is executed that brings the view back to its original position and the tether layer back as well. Now my only real problem is that while the view and the tether are animating the view doesnt respond to tap gestures…
Anyone know some tricks? I hope my explanation was understandable and thanks in advance!
(if the tethered view concept is not clear there is a free app called discovr apps which will give an example).
I'm assuming that you are using the [UIView animateWithDuration: delay: options: animations: completion:]; method of animating.
If so, you need to pass UIViewAnimationOptionAllowUserInteraction as an option to get the animated view to respond to touches while it is animating.
(Swift 3) Pass .allowUserInteraction option
UIView.animate(withDuration: 0.75, delay: 0.0, options: [.allowUserInteraction], animations: {
// Desired animation(s)
}, completion: { (finished: Bool) in
// Completion
})
You need to set two options - UIViewAnimationOptionAllowUserInteraction and UIViewAnimationOptionAllowAnimatedContent. First lets you interact with views during animation, second forces to redraw views on every frame of animation and not use snapshots of beginning and ending frames.

Resources