How to avoid an animation to disable touch interaction (scroll, swipe, etc) - ios

Im trying to make an animation over a view in my ViewController.
My problem is that the scroll/swipe gestures over other elements like UITableViewControllers or UIPageViewControllers get disabled until the animation finishes.
How can I avoid this behaviour?

Do your animations using allowUserInteraction option:
UIView.animate(withDuration: duration, delay: 0, options: .allowUserInteraction,
animations: {
// Your animations here
},
completion: nil
)

Related

UITableView animation that starts quickly and slows down by the end

I am programatically scrolling the table with animation. I want this scrolling to be same as the user scrolling (fast at beginning and slow at end). How to perform an animation that start with speed and then go slow in the end?
You can basically use animation block with UIViewAnimationOptions.curveEaseOut of the scrollView / tableView.
curveEaseOut (From documentation):
An ease-out curve causes the animation to begin quickly, and then slow
as it completes.
UIView.animate(withDuration: 0.5, delay: 0.0, options: [.curveEaseOut], animations: {
self.tableView.setContentOffset(CGPoint(0, 100), animated: false)
}, completion: nil)
That way you control over the animation duration and manner.

Custom Transition Animation with User Interaction Enabled

I have a custom full screen alert with a low alpha background. The default modal animation slides from bottom to top. I would like the alert to fade-in and fade-out. I am UIViewControllerTransitioningDelegate + UIViewControllerAnimatedTransitioning. In my animateTransition(using:) method I have something similar to this:
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
if let toView = transitionContext.view(forKey: .to) {
toView.frame = containerView.frame
containerView.addSubview(toView)
UIView.animate(withDuration: duration, delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0,
options: UIViewAnimationOptions.allowUserInteraction,
animations: {toView.alpha = 1})
transitionContext.completeTransition(true)
}
}
The problem is that the fade effect looks good at around 1-1.5 seconds; however, the user cannot tap any buttons such as "yes" or "no" during this transition animation. I attempted the following:
Move the call transitionContext.completeTransition(true) outside the completion handler for the animation so it happens as soon as the animation starts
Adding the UIViewAnimationOptions.allowUserInteraction option
Starting the alpha at 0.1 (and 1.0) as was suggested in another post
I did notice UIViewControllerInteractiveTransitioning but it seems this is only allowing interaction with the animation itself
The only way I can see this working is if I do the fade-in effect in viewDidAppear in the VC and the fade-out effect in UIViewControllerAnimatedTransitioning. Feels bad man. What is the correct way to do this?

Can all constraints in swift 3 be animated?

I want to animate a view like using the following code:
UIView.animate(withDuration: 2.7, delay: 0.1, options: .allowAnimatedContent, animations: {
self.AVCenterY.constant = 0.8
}, completion: nil)
But it happens so fast it seems like it is not animated. On the other hand, when I animate the property alpha it is animated (it takes the 2.7 seconds to change). I used 2.7 sec to make sure the problem was that I was using a small duration time.
Constraints cannot be animated at all. It is the act of layout that can be animated:
UIView.animate(withDuration: 2.7, delay: 0.1, options: .allowAnimatedContent, animations: {
self.AVCenterY.constant = 0.8
theView.superview?.layoutIfNeeded() // *
}, completion: nil)
When we animate the act of layout (or when the runtime does so), then any constraint changes are also automatically animated.
Note that what I animate is the layout of the superview of the view that is to move. I called it theView but that is just something I made up. You will need an outlet to that view so that you can get its superview, and use the name of that outlet.

UITextField disappears when tapped after animation

After making an animation on a UITextField, if I tap on my UITextField, it disappears. Why does this happen and how can I fix it? I'm not sure how to search for this online. Here's my animation code that I'm doing in viewDidAppear
UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: [], animations: {
self.userName.center.x += self.view.bounds.width
self.userName.alpha = 1.0
}, completion: nil)
Before this I set the UITextField to be off the screen. So what my animation is supposed to do is start from outside of the screen and animate it to be visibly in the center of the screen. Don't know if that makes a difference in this question though.
The animation works great, it's just that when I try to tap on the UITextField to enter a username, the entire UITextField just disappears and I'm left with just a keyboard. I'm sure it's something simple I'm missing. Can someone lead me in the right direction?

swift animateWithDuration animation not right

I am hiding my navigation bar and a UIView under it that acts as a extension bar to it when I scroll my page.
My app is built like:
VC that holds a container view with an embedded table view.
From the table view I have delegates that notify VC1 once a user scrolls up or down.
My problem now is that the animation dont looks that good. What I am trying to do is to animate the extension bar to animate up or down with a fade in or fade out effect as well. When that occurs I also update the top contraint on my container view so that the table view will fill the whole screen. (I am not sure if I use layoutneeded() right or if something else should be used when updating constraints)
My code:
func ContainerTableViewControllerScrolledUp(controller: ContainerTableViewController) {
self.navigationController?.setNavigationBarHidden(false, animated: true)
println("UP")
UIView.animateWithDuration(
1.5,
delay: 0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: nil,
animations: {
self.extensionV.alpha = 1
self.tableVConst.constant = 0
}, completion: { finished in
self.view.layoutIfNeeded()
}
)
}
func ContainerTableViewControllerScrolledDown(controller:ContainerTableViewController) {
self.navigationController?.setNavigationBarHidden(true, animated: true)
println("DOWN")
UIView.animateWithDuration(
1.5,
delay: 0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: nil,
animations: {
self.extensionV.frame.origin.y = CGFloat(-10)
self.tableVConst.constant = -41
self.extensionV.alpha = 0
}, completion: { finished in
self.view.layoutIfNeeded()
}
)
}
extensionV is the extension view
tableVConst is the top constraint for my container view that holds my table view
So how should I edit my code in order to get the extension view to animate up/down with a fade in/fade out effect?
Instead of calling self.view.layoutIfNeeded() in the completion block, try calling it inside the animation block on the last line before it returns.

Resources