how to enable user interaction on animated objects? - ios

For some reason animated cell disable interaction over them, which makes my collection view scrolling useless. If I put my hand in between two cells, the scrolling works, so the animation somehow enters disables touch interaction over them. The animation goes on forever:
UIView.animateWithDuration(0.2,
delay: 0.0,
options: UIViewAnimationOptions.Autoreverse | UIViewAnimationOptions.Repeat,
animations: {
cell.transform = CGAffineTransformMake(1.0, 0.0, skew, 1.0, 0.0, 0.0);
},
completion: nil);
How can I work around this problem?

Try adding UIViewAnimationOptions.AllowUserInteraction flag ?

Related

Animating position of UIButtons causes them to stop receiving touch actions

In my app I have several buttons that, after a separate button is pressed move to new positions in a UIView animation. The animation itself works perfectly, but the problem is, after the animation, the four buttons stop responding to touch actions. Here's my current code:
UIView.animate(withDuration: 1.0, delay: 0.0, options: [.allowUserInteraction], animations: {
self.hexagon.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 2)
self.tileB.center.x += self.tileB.bounds.width
self.tileB.center.y += self.tileB.bounds.height
self.tileF.center.x -= self.tileF.bounds.width
self.tileF.center.y += self.tileF.bounds.height
self.tileH.center.x -= self.tileH.bounds.width
self.tileH.center.y -= self.tileH.bounds.height
self.tileD.center.x += self.tileD.bounds.width
self.tileD.center.y -= self.tileD.bounds.height
}, completion: nil)
I have tried many other methods, including setting frames and bounds, but none of them have worked correctly.
The animation itself works perfectly, but the problem is, after the animation, the four buttons stop responding to touch actions
The reason is probably that after the animation, the buttons have moved out of their superview's bounds. A view outside of its superview is untouchable, even if it is visible.
One way to confirm this is to set the superview's clipsToBounds to true and do the animation. The buttons will vanish by the end of the animation, proving that they have moved outside their superview.

Animating height constraints using easing curves

Is there any way to animate a height constraint using an easing curve? I'm thinking of maybe some way to set up a CAKeyFrameAnimation with the values and timings I'd like, and somehow have it affect the height constraint.
I'm not sure if there's a separate animation calss for constraints that I can utilize for constraint keyFrames, or if there's something I'm missing with CAKeyFrameAnimation that would allow me to use that class, or if it's not possible.
Edit: Here's what I'm trying to make work for me, if anyone knows if I'm on the right path or not I'd appreciate some guidance:
self.heightConstraint.constant = newHeight
let animation = CAKeyframeAnimation(keyPath: "frame.size.height")
animation.values = [self.frame.size.height, newHeight]
animation.keyTimes = [0, 1]
animation.duration = self.animationDuration
animation.delegate = self
self.layer.add(animation, forKey: "heightChange")
newHeight would be whatever I want the height to be. But this just pops the view to be taller without any animation. Am I using this correctly? Is this possible to do with constraints?
Edit 2: I should add, I want to use more complex easing functions than the defaults Apple provides as part of UIView.animate(withDuraiton:....
There is no need to use CAKeyframeAnimation. A UIView animation will do easing on animations to a constraint, just like any other animation:
myConstraintOutlet.constant = someNewValue
UIView.animate(
duration: 0.5,
delay: 0.0,
options: .curveEaseInOut, //Use ease-in, ease-out timing.
animations: {
self.view.layoutIfNeeded()
},
completion: nil)
Edit:
If you want custom timing, you could also use the UIView-based keyframe animation with the method animateKeyframes(withDuration:delay:options:animations:completion:) (UIView animation is a whole lot easier to use than CAAnimations.)
Edit #2:
Or, if all you need is a different cubic easing curve, you can do that too. See the very last bit at this link: https://medium.com/#RobertGummesson/a-look-at-uiview-animation-curves-part-3-edde651b6a7a
The key bit is this code snippet from that link:
circleView.transform = CGAffineTransformMakeScale(0, 0)
let timingFunction = CAMediaTimingFunction(controlPoints: 5/6, 0.2, 2/6, 0.9)
CATransaction.begin()
CATransaction.setAnimationTimingFunction(timingFunction)
UIView.animateWithDuration(1) {
self.circleView.transform = CGAffineTransformIdentity
}
CATransaction.commit()
(That's not my code, it's Robert Gummesson's, from the link above. All credit for writing it goes to him.)

Springy animation on scaling up UIImageView

I have a UIImageView with a circular png inside. I am trying to initialise it with 0 x 0 and scale it up with an ease, so it looks like a bubble effect.
In viewDidLaod(), I initialsied it with CGSize however I couldn't figure out how to apply animation so it doesn't just scales up with a same speed, but it looks like springy (I mean, if it will come to 100 x 100, it works like 'boing' effect and it passes 100 x 100 too, but when animation settles, it finishes at 100x100) .
logoCircularBg.frame.size = CGSize(width: 0, height: 0)
logoCircularBg.hidden = false
Something like this but starting from 0x0 and stopping at 100x100, and with UIImageView.
Here is a code example that I used for animating a UIImageView with a springy/bounce animation like that one that you have posted. Before starting the animation I scale down the imageView to 1% of its size. The animation then scales the imageView back to 100%.
self.myImageView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
UIView.animate(
withDuration: 1.2,
delay: 0.0,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 0.2,
options: .curveEaseOut,
animations: {
self.myImageView.transform = CGAffineTransform(scaleX: 1, y: 1)
},
completion: nil)
For a "springy" animation, call UIView's animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:). A lower damping value will give increased oscillation at the end of the animation, just as in your screencast.
(When you form this animation, I would suggest animating the view's scale transform, not its frame.)

Create custom animation like transitionWithView block

I am using transitionWithView animation block to animate view. This block is called when user swipe the view in left or right direction. It works fine. But I want to create my own custom animation like view gets changed from left to right direction. I don't know how to achieve this. I am using UIViewAnimationOptionTransitionCurlUp for right to left swipe
and UIViewAnimationOptionTransitionCurlDown for left to right swipe in UIViewAnimationOptions.
[UIView transitionWithView:self.view duration:0.6 options:UIViewAnimationOptionTransitionCurlUp animations:^{
setDataInLayout();
} completion:^(BOOL finished) {
[scrollViewContent setContentOffset:CGPointZero animated:YES];
[self.delegate updatePaginationCounter:_currentStoneIndex];
}];
You have to implement this animation by yourself. I would use UIView animation API like:
UIView.animateWithDuration(0.6, animations: {
// apply 2D transformation to the view, or use any other animatable property
self.view.transform = CGAffineTransformMakeRotation(fullRotation)
} completion: {finished in
// you completion block
})
Here is the list of UIView's animatable properties. For more complex animations you can use the keyframe-based animation:
UIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: {
// add your keyframe animations here
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1/2, animations: {
self.view.transform = ...
})
UIView.addKeyframeWithRelativeStartTime(1/3, relativeDuration: 1/2, animations: {
self.view.transform = ...
})
}, completion: {finished in
// completion block
})
}

Custom UIView scaling using CGAffineTransformScale

I'm learning to develop for iOS, and as part of education process I have created custom UIView which uses drawRect to draw it's contents (Core Graphics + UIBezierPath based). Everthing works as expected, view is dynamic and renders it's contents depending on it's width/height. Now I want to add dissolve animation which should look like scaling from 100% to 0%. I have written this code to do it:
[UIView animateWithDuration:1 delay:0
options: UIViewAnimationOptionBeginFromCurrentState
animations: ^{
for (CardView *cardView in self.cardsViews) {
cardView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.01, 0.01);
}} completion:nil];
However, this code DOES NOT scales my view from 100% to 0%. It just makes cards to dissapear (at most). I have tried many ways of doing scaling, but only effect I have reached so far is zooming from 0% to 100%. This my view does perfectly, but not reverse scaling... Also, it DOES NOT scales up/down even if I try to apply non-animated transformation such as:
cardView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.5, 0.5);
I see that my view look changes A BIT, but not scales to 50%, that's for sure. When I try to apply exactly same animation logic to UILabel, it works perfectly! What have I missed developing custom UIView? Why scaling view may malfunction?
Thanks a lot in advance!
UPDATE #1 This code makes my view exactly twice as big and than scales it back to original size:
[UIView animateWithDuration:5 delay:0
options: UIViewAnimationOptionBeginFromCurrentState
animations: ^{
for (CardView *cardView in self.cardsViews) {
cardView.transform = CGAffineTransformMakeScale(0.5, 0.5);
}
} completion:nil];
It is simple 100% to 0% using CGAffineTransformScale:
cardView.view.transform =CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
[UIView animateWithDuration:0.3/1.5 animations:^{
cardView.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.1, 0.1);
} completion:^(BOOL finished)
{
NSLog(#" Animation complet Block");
}];
What you can try is setting the contentMode of the view to UIViewContentModeRedraw and adding another animation option - UIViewAnimationOptionAllowAnimatedContent - in animateWithDuration method.
Swift scaling from 120% to 100%:
logoView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
UIView.animate(withDuration: 0.55, delay: 0.1, options: [.curveEaseOut], animations: {
self.logoView.transform = .identity
self.view.layoutIfNeeded()
}, completion: { _ in
})

Resources