360 ImageView Rotation - Speed based on userValues - ios

I have a view which users can key in some values into six textview boxes, which later get saved into a plist. My next view has a imageview which has a circle I designed. I am want to animate this circle with a 360 rotation based on how many textfields have values.
If the user types values for one textfield it goes at 1x speed.
If the user types values for two textfield it goes at 2x speed.
etc.
Can anyone please tell me how I can create this clockwise rotated animation of my imageView with a speed which is set based on the textfields which have values. All values are stored within the p.list. The animation needs to be on infinite too.
Thanks Guys,

You use the animateWithDuration: animations: completion: to animate UIView objects.
It is used like this:
[UIView animateWithDuration:duration animations:^(void)animations
completion:^(BOOL finished)completion];
Inside the animations block you enter the animation you want like for example in your case
imageView.transform = CGAffineTransformMakeRotation(M_PI*2); // This will rotate it 360 degrees
And to make it infinite you can add this method inside a function and in the completion block you call that function to make it infinite.

Related

Flipping image after rotation issue (need to do both, only does one)

I have a UIImage on my storyboard, and I have just rotated it( i can rotate it any number of degrees). The code for the rotation is below:
let DegreesFloat = Double(-Degrees) * M_PI/180
self.imageView.transform = CGAffineTransformMakeRotation(CGFloat(DegreesFloat))
By the way, degrees in the first line of code, is an integer I enter into a text field. When the view loads, I have this...
self.imageView.transform = CGAffineTransformMakeScale(1, -1);
to keep the image upside down, cause that's just how I need it to be. The issue is that when I rotate the image, it cancels out the flip, and flips it back to its original flip (without the 2nd paragraph of code). I need it to keep it's upside down flip, while performing it's rotation.
When I add the flip code after the rotate code, it just cancels out the rotate code. I have no idea how to do this, but I just need it to stay upside down, while correctly performing a rotation, and NOT flipping itself back to its original right-side up orientation.
I think what you are asking is how to make multiple transform commands together. The transformations are actually a matrix telling the image later what to do. Use a CGAffineTransformConcat to apply multiple transformations. Refer to the Apple documentation

How to rotate a view in place after transform as been applied?

I'm using a variant of this code to slighty rotate a UIButton about its center:
CGFloat jiggleAngle = (-M_PI * 2.0) * (1.0 / 64.0);
self.transform = CGAffineTransformRotate(self.transform, jiggleAngle);
This code generally works as expected and rotates the button in-place, about 12 degrees counter-clockwise. However, this only works if I do not reposition the button inside my layoutSubviews method. If I do any repositioning of the button at all from its initially laid-out location, the attempt to rotate above results in the button's disappearance. If the angle I choose for rotation is an exact multiple of 90 degrees, the rotation works somehow even after a move in layoutSubviews.
I understand that my button's transform is being altered in layoutSubviews and this results in the subsequent weirdness when I attempt to rotate it with the above code. I have currently worked around this problem by placing the button I wish to rotate inside another UIView and then moving that view around as desired, but I'd like a better solution that doesn't require redoing my screen layouts.
How can I adjust/alter my button's transform after a move, so that this rotation code continues to work as expected?
The problem you are facing is that a view's frame is "undefined" if it's transform isn't the identity transform.
What you should do is use the view's center property to move it around. That works even if you've changed it's transform.
You can also apply a rotation to the view's layer instead of the view (although be aware that the layer transform is a CATransform3D, a 4x4 transformation matrix instead of a 3x3, so you need different methods to manipulate it.)

iOS game - animate tile by tile

I'm developing a tile based iOS game. Objects (UIViews) are drawn above the tile map and should walk around, tile by tile.
I'm using a simple UIView animation to do that:
[UIView animateWithDuration:0.20 delay:0 options:UIViewAnimationOptionCurveLinear animations:^(void) {
// set frame
// set rotation
} completion:^(BOOL finished){
// call method to start animation again
}];
The problem is that even when only animating about 5 objects it isn't smooth. After each animation there is a very small pause. Because it should be perceived as one animation (not tile by tile) it is noticable.
I need to do some checks for each move (1 move = 1 tile), so I can't just use one big animation. The checks are done independently and should update the data before the animation is finished. So I don't think the lag is because of that.
Are there any other ways on solving this? Maybe with Sprite Kit?
Even when I rewrote the animation logic so that the animation distance would be as long as possible it was still very jerky with a few objects.
It seems that animating multiple UIImageViews with transparency isn't a very good idea.
I'm now using Sprite Kit and everything is smooth and running at 60fps. It wasn't a big change, as Sprite Kit is quite simular.

How to move graphic in an arc path on iOS... as in a meter or clock face

This is the result of what I want to achieve:
(source: mouseaddict.com)
I have static images for my app, but i want to add motion to them.
Imagine a meter. It has a needle that is locked at the bottom (at 6:00 on a round-clock-style-face) and whose needle-top swivels from left to right in an arc. the arc (zero) starts with the needle pointed toward (roughly) the 9:30 position on a round-clock-style-face and the top-most part of that arc should end at roughly 2:30 on a round-clock-style-face.
I have several graphical elements 1) the round meter face (png) and 2) the verticaly oriented png file of a meter needle. I need to cause the needle to move within the round face in an arc'ing pattern.
So, assuming the two requirements above, what is the best way to swivel the needle within the meter using animation?
I have seen this: Speedometer -- but is this the best way? My main issue is that I want the needle locked at the bottom and move left-to-right only a small amount..as WELL as the fact that there is little (actually no) documentation on it. Things like "calculateDeviationAngle" are unexplained.
Also the Speedometer seems to move a large amount and the pivot point on that example would not work...(i dont think)
I would like to call this with a command like:
[self moveNeedleToPosition:degreeOrClockFaceNumber] and have it move from it's current position to a bit past the degreeOrClockFaceNumber and bounce back to rest at degreeOrClockFaceNumber.
TIA
I did the following: I broke the image up into several pieces. The outline (black) portion, the backgrounds and the needle. Each piece having the same exact "footprint" (shapes).
Assuming theImageView is the imageView for the needle (layered on top of the other two imageViews), I created the following function:
-(void) rotateNeedle:(UIImageView *)theImageView toAngle:(float) theAngle
{
[UIView animateWithDuration:0.5
delay: 0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
theImageView.transform =CGAffineTransformMakeRotation((M_PI / 180) * (theAngle + 10));
}
completion:^(BOOL finished){
//
[UIView animateWithDuration:0.5
animations:^{
theImageView.transform = CGAffineTransformMakeRotation((M_PI / 180) * theAngle);
}];
}];
}
The first animation in the block performs the "shoot-past" portion of the animation...ie: moving 10 degrees past the actual value. The second animation in the completion block then "bounces" the needle back to the correct value. The speed of these animations create the physics effect. It works quite well for me.

How to keep iOS animation smooth with many subviews

I am trying out different looks of a little game I am writing to play with animation on iOS.
My goal is this to have a grid of tiles which based on gameplay changes the display of each tile to one of a set of images. I'd like each tile (up to 24x24) to flip around when its face changes. As the game progresses, more and more tiles need to be flipped at the same time. In the first implementation where I tried to flip them simultaneously the animation got very jerky.
I changed my approach to not flip them all at once, but just a few at a time, by scheduling the animation for each tile with a slightly increasing delay per tile, so that when say the 10th tile starts animating, the first one is already done. It takes little while longer for the whole process to finish, but also leads to a nice visual ripple-effect.
However, one problem remains: At the beginning of a game move, when the player picks a new color, it takes a few fractions of a second on the device, before the animation starts. This gets worse as the game progresses and more flips need to be scheduled per move, up to the point where the animation seems to hang and then completes almost instantly without any of the frames in between being actually discernible.
This is the code (in my UIView game grid subclass) that triggers the flipping of relevant tiles. (I removed an optimization that skips tiles, because it only matters in the early stages of the game).
float delay = 0.0f;
for (NSUInteger row=0; row<numRows; row++) {
for (NSUInteger col=0; col<numCols; col++) {
delay += 0.03f;
[self updateFlippingImageAtRow:row col:col delay:delay animated:YES];
}
}
The game grid view has an NSArray of tile subviews which are addressed using the row and col variables in the loop above.
updateFlippingImageAtRow:col:delay:animated is a method in my FlippingImageView (also a subclass of UIView) boils down to this (game logic omitted):
-(void)animateToShow:(UIImage*)image
duration:(NSTimeInterval)time
delay:(float)delay
completion:(void (^)(BOOL finished))completion
{
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:self
cache:YES];
self.frontImage = image;
}
completion:completion
];
}
Works fine, however, I conclude from the Instruments measuring which tells me that my time is spent in the animation block, that as the game goes on and the number of tiles to flip goes up, that the number of animations that get scheduled at the very beginning of the operation is a problem, and that the system then tries to catch up by dropping frames.
Any suggestions how to improve the performance of this? The exact timing of the animation is not really important.
You can think about doing this with CoreAnimation and CALayers instead of UIViews. It is incredebly powerful and optimized framework.
It's not an easy thing, you'll have to recode at least some of your classes (view hierarchy and hit tests are the first things that come to my mind), but it's worth a try and it's rather painless process, because CALayer is very similar to UIView.
Next step is OpenGL. It definitely can operate several hundreds of objects in realtime, but it requires much more work to do.
You might want to try using CoreAnimation instead. One way to do the flip animation would be:
Create a CABasicAnimation that animates the first half of the flip (rotation along the y axis).
In the delegate method animationDidStop:finished: you set the new image and then create a new animation that animates the second half.
You simply apply the animation to the layer property of your view.
Note that you can use setValue:forKey: to "annotate" an animation (remember what object the animation is about). When you add an animation to a layer it gets copied, not retained, so you can't identify it by simply comparing pointer values.

Resources