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?
Related
I am attempting to add a UIView Animation/fade-in effect to my function:
self.view.bringSubview(toFront: self.webView)
I've tried implementing it programmatically, but the UIView doesn't animate; instead, it just shows it immediately without the fade-in effect:
UIView.animate(withDuration: 1, animations: {
self.view.bringSubview(toFront: self.webView)
}, completion: nil)
How would I go about implementing an animation for the bringSubview(_: ) and sendSubview(_ : ) functions? I've tried looking everywhere, but no one seems to have the answer.
You can't use UIView.animate like that. It only works on certain properties. In this case, you need to animate the alpha property.
Before you start animating, set the view's alpha to 0 then bring it to front:
self.webView.alpha = 0
self.view.bringSubview(toFront: self.webView)
// After that you animate the alpha:
UIView.animate(withDuration: 1, animations: {
self.webView.alpha = 1
}, completion: nil)
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
)
I'm performing the following animation on a UIButton called "view":
UIView.animateWithDuration(duration, animations: {
self.view.transform = CGAffineTransformMakeScale(0.5, 0.5)
})
When the animation runs, it immediately doubles the size of the UIButton, then shrinks it back to its original size. So the animation does work.
But what I would like to have happen is for the animation to start with the UIButton at its original size and then shrink it to half of that size.
Basically, I want the original size of the UIButton to appear at the start of the animation, not the end. How can I do this?
(I tried changing the view.frame.size.height and width properties but that didn't seem to change the appearance of the UIButton or the animation on it.)
You may have conflicting animations.
UIView.animateWithDuration(
duration,
delay: 0,
options: .BeginFromCurrentState,
animations: { () -> Void in
self.view.transform = CGAffineTransformMakeScale(0.5, 0.5)
}) { (completed:Bool) -> Void in
self.view.transform = CGAffineTransformMakeScale(0.5, 0.5)
// or, to reset:
// self.view.transform = CGAffineTransformIdentity
}
Starting this animation from .BeginFromCurrentState may reduce or remove glitches entirely, and taking action upon completion (which logic you can base upon completed:Bool) will also tell Core Animation what to do when an animation is interrupted.
How can I animate a stack view to slide up starting from x=0 up to y=500, I have the following method in the viewDidLoad() which does a growing effect.
StackView.transform = CGAffineTransformMakeScale(0.0, 0.0)
And then I added a growing effect in the viewDidAppear() method
UIView.animateWithDuration(0.4, delay: 0.0, options: [], animations: {
self.StackView.transform = CGAffineTransformIdentity
}, completion: nil)
After the viewDidLoad method executes, the stack view is minimized. When the viewDidLoad method completes, the viewDidAppear method is invoked, and the animation begins and the stack view begins to grow. The animation stops when the stack view reaches it's original size.
Although is a nice effect that's not what I want to accomplish, I want the animation to slide up from x = 0 and stops at y = 500 I tried to add the following code in the viewDidLoad to accomplish this effect, but I still get the same growing effect. Any suggestions on how to accomplish this?
StackView.transform = CGAffineTransformMakeTranslation(0, 500)
You´re almost there just make a few changes
// These values depends on the positioning of your element
let left = CGAffineTransformMakeTranslation(-300, 0)
let right = CGAffineTransformMakeTranslation(300, 0)
let top = CGAffineTransformMakeTranslation(0, -300)
UIView.animateWithDuration(0.4, delay: 0.0, options: [], animations: {
// Add the transformation in this block
// self.container is your view that you want to animate
self.container.transform = top
}, completion: nil)
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.