Change UIView's super view with animation in Swift - ios

I have a VideoView (it is a child view of UIView).
By default, it is added to a UIView which is small view in the corner of the screen (I called it ParrentView1).
I have a button to zoom out VideoView. This button performs an action that removes VideoView from ParentView1 and adds it to a bigger view (called ParrentView2).
When I perform the code below, it works but the animation is weird. All I need is a zoom out animation from ParrentView1 to ParrentView2.
Here is my code:
VideoView.removeFromSuperview()
ParrentView2.addSubview(VideoView)
UIView.animate(withDuration: 0.8, delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: 1,
options: .curveEaseOut,
animations: {
VideoView.frame = ParrentView2.bounds
}, completion: nil)
thanks for helping

The likely cause is that when adding it to the other view, it gets assigned a different frame. The solution is to make sure the animation starts at the original location. Something like:
CGRect originalRect = ParrentView2.convert(VideoView.frame, from:VideoView.superView);
VideoView.removeFromSuperview()
ParrentView2.addSubview(VideoView)
VideoView.frame = originalRect;
UIView.animate(withDuration: 0.8, delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: 1,
options: .curveEaseOut,
animations: {
VideoView.frame = ParrentView2.bounds
}, completion: nil)
An improvement point: note that it is customary in Swift to start variable names with a lower case letter. It gets confusing when they don't.

Related

How to create bouncing effect in swift?

I have created a popup in swift using UIView and I want to bounce it when displaying, but I don't know how to do that. I want to make the same effect as seen below:
You should use UIView.animate with usingSpringWithDamping and initialSpringVelocity parameters.
Eg:
// Change position of view
UIView.animate(withDuration: 1.0, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: [], animations: {
// Call layoutIfNeeded()
})
Or you can change view's position in animation completion block. But it's not recommended.

TableView animation when the cell is tapped

I would like to animate the tableView cell when the user put is finger on it like in this image
and when the user stop pressing, the cell come back in the original size (my tableView is not using a custom cell but the default UItableViewCell). I looked around the net to find some tutorial or something useful but nothing, someone can tell me how can i do?
You can do it like this:
On Touch Down Event for UITableViewCell:
UIView.animateWithDuration(0.2, delay: 0.1, usingSpringWithDamping: 0.9, initialSpringVelocity: 5, options: [],animations: {
self.contentView.transform = CGAffineTransformMakeScale(0.95, 0.95)
}, completion: { finished in
})
And On Touch Up Event for UITableViewCell:
UIView.animateWithDuration(0.2, delay: 0, usingSpringWithDamping: 0.9, initialSpringVelocity: 5, options: .CurveEaseIn,animations: {
self.contentView.transform = CGAffineTransformMakeScale(1, 1)
},completion: { finished in
})
Hope this will help you.

UIView is not animating properly

so i'm trying to move my UIView out of frame, but instead of getting out of view it's just Animating to the center of ViewController
My code:
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 4, initialSpringVelocity: 1.0, options: [], animations: ({
self.myTextField.center.x = 1300 // just a temporary value
}), completion: nil)
print(self.passwordTextField.center.x)//---> 1300
anyone knows why is it happening? and how can i fix it?

Perfect Swift3 Boing

To animate a bar opening...
#IBOutlet var barHeight: NSLayoutConstraint!
barHeight.constant = barShut?30:100
self.view.layoutIfNeeded()
t = !barShut?30:100
UIView.animate(withDuration: 0.15,
delay: 0,
options: UIViewAnimationOptions.curveEaseOut,
animations: { () -> Void in
self.barHeight.constant = t
self.view.layoutIfNeeded()
},
completion: {_ in
Screen.barShut = !Screen.barShut
}
)
That's great ...
But how would you make it boing like this?
(The only way I'd know to do this is, use CADisplayLink, with a few lines of code for a spring decaying.) Is this available in UIKit?
You can use the spring animation method that is built in to UIView:
func toggleBar() -> Void {
self.view.layoutIfNeeded()
let newHeight:CGFloat = !barShut ? 30:100
barShut = !barShut
barHeightConstraint.constant = newHeight
UIView.animate(withDuration: 1.5, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 3, options: [], animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
You will want a longer animation duration than 0.15 of a second in order for the bounce to seem realistic; I think the values I have look pretty good, but you can play with them to get the exact effect you are after.
Since the animation duration is longer, I found that I could tap the button the triggered the open/shut while the previous animation was still running. Setting barShut in the completion block meant that the bar didn't react to all taps. I moved the toggle outside of the animation to address this.

UIView scale animation overshoots when changed

When I animate a change to a view's transform, then reset that change in another animation before the first animation finishes, everything's great (shown here with a rotation). The animation smoothly switches to the new target:
But when I do this with a scale, the animation overshoots magnificently:
Here's the breaking code:
UIView.animateWithDuration(1) {
self.someView.layer.transform = CATransform3DMakeScale(0.001, 0.001, 1)
}
UIView.animateWithDuration(1,
delay: 0.5,
options: nil,
animations: {
self.someView.layer.transform = CATransform3DIdentity
}, completion: nil
)
Has anyone else seen this? Am I doing something wrong?
EDIT: And is there a good workaround?
EDIT 2: I believe this is a duplicate of this question and am voting to close.
This blog post provides the answer: in iOS 8, UIView animations are additive, and this has an unfortunate result with scale animations.
Basically, the second animation happens together with the first animation. The only solution is to explicitly remove the original animation before starting a new one:
view.layer.transform = view.layer.presentationLayer().transform
view.layer.removeAllAnimations()
Hi I'm not quite sure what your looking for but if you want the view to go back to it's original scale you'd add the .Autoreverse flag.
UIView.animateWithDuration(1, delay: 0, options: .Autoreverse | .Repeat, animations: {
myView.layer.transform = CATransform3DMakeScale(0.001, 0.001, 1)
}, completion: nil)
While if you wanted to string animations together I'd do it within UIView.animateKeyframesWithDuration()
UIView.animateKeyframesWithDuration(2, delay: 0.0, options: nil, animations: {
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.5, animations: {
// Animation 1
})
UIView.addKeyframeWithRelativeStartTime(1, relativeDuration: 0.5, animations: {
// Animation 2
})
}, completion: nil)

Resources