how to rotate an image in different direction using single button? - ios

I've a problem while im adding the code of case switch or if else with a single button so that it could rotate an image when i single press it and than when i again tap it, it should rotate in some other direction.

try this,
here yourImage is the image view which is to be rotated
- (IBAction)rotateImage:(UIButton *)sender // your button action method
{
if (!sender.selected)
{
[sender setSelected:YES];
[UIView animateKeyframesWithDuration:2.0
delay:0.0
options:UIViewKeyframeAnimationOptionCalculationModeLinear
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0
relativeDuration:1/3.0
animations:^{
yourImage.transform = CGAffineTransformMakeRotation(2.0 * M_PI / 3.0);
}];
[UIView addKeyframeWithRelativeStartTime:1/3.0
relativeDuration:1/3.0
animations:^{
yourImage.transform = CGAffineTransformMakeRotation(4.0 * M_PI / 3.0);
}];
[UIView addKeyframeWithRelativeStartTime:2/3.0
relativeDuration:1/3.0
animations:^{
yourImage.transform = CGAffineTransformMakeRotation(0);
}];
}
completion:^(BOOL finished) {
}];
}
else
{
[sender setSelected:NO];
[UIView animateKeyframesWithDuration:2.0
delay:0.0
options:UIViewKeyframeAnimationOptionCalculationModeLinear
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0
relativeDuration:1/3.0
animations:^{
yourImage.transform = CGAffineTransformMakeRotation(4.0 * M_PI / 3.0);
}];
[UIView addKeyframeWithRelativeStartTime:1/3.0
relativeDuration:1/3.0
animations:^{
yourImage.transform = CGAffineTransformMakeRotation(2.0 * M_PI / 3.0);
}];
[UIView addKeyframeWithRelativeStartTime:2/3.0
relativeDuration:1/3.0
animations:^{
yourImage.transform = CGAffineTransformMakeRotation(0);
}];
}
completion:^(BOOL finished) {
}];
}
}

Related

iOS: Repeat animation block until an event completes

I have the following animation block, which spins a button once. I would like to continue the button spinning until the refreshPendingRequests method has finished.
The refreshPendingRequests method retrieves data from my server, so I would like continue spinning the button until I have retrieved the data.
CGFloat direction = 1.0f; // -1.0f to rotate other way
refreshButton.transform = CGAffineTransformIdentity;
[UIView animateKeyframesWithDuration:1.0 delay:0.0
options:UIViewKeyframeAnimationOptionCalculationModePaced | UIViewAnimationOptionCurveEaseInOut
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
refreshButton.transform = CGAffineTransformMakeRotation(M_PI * 2.0f / 3.0f * direction);
}];
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
refreshButton.transform = CGAffineTransformMakeRotation(M_PI * 4.0f / 3.0f * direction);
}];
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
refreshButton.transform = CGAffineTransformIdentity;
}];
}
completion:^(BOOL finished) {
[self performSelector:#selector(refreshPendingRequests) withObject:nil afterDelay:0.0];
}];
Does anyone know if there is some type of repeats property that I could call or how I can perform this animation until the refreshPendingRequests event is finished?
There is an option for this indeed: UIViewKeyframeAnimationOptionRepeat.
Pass that option in, and pass nil for your completion block, since you shouldn't need it.
[UIView animateKeyframesWithDuration:1.0 delay:0.0
options:UIViewKeyframeAnimationOptionCalculationModePaced | UIViewAnimationOptionCurveEaseInOut | UIViewKeyframeAnimationOptionRepeat
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
refreshButton.transform = CGAffineTransformMakeRotation(M_PI * 2.0f / 3.0f * direction);
}];
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
refreshButton.transform = CGAffineTransformMakeRotation(M_PI * 4.0f / 3.0f * direction);
}];
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
refreshButton.transform = CGAffineTransformIdentity;
}];
}
completion:nil];
Then when your refresh completes:
[refreshButton.layer removeAllAnimations];

"EXE_BAD_ACCESS" in completion Handler

I am getting "EXE_BAD_ACCESS" But i dont know where i have done mistake
Please have a look on the code and let me know the mistake.
+ (void)showBounceAnimatedView:(UIView *)popUp completionBlock:(void (^)())completionMy {
popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.7, 0.7);
[UIView animateWithDuration:0.3/1.5 animations:^{
popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3/2 animations:^{
popUp.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3/2 animations:^{
popUp.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
completionMy(); <-----------
}];
}];
}];
}
The arrow is showing where i am getting is error;

Animating annotationViews (loop animation), didSelectAnnotationView doesn't work

So I am trying to animate my annotationViews using the following code :
- (void)mapView:(MKMapView *)mapView
didAddAnnotationViews:(NSArray *)annotationViews
{
LLAnnotationView *aV;
for (aV in annotationViews) {
// Don't pin drop if annotation is user location
if ([aV.annotation isKindOfClass:[MKUserLocation class]]) {
continue;
}
aV.transform = CGAffineTransformMakeScale(0, 0);
aV.alpha = 0.1;
dispatch_async(dispatch_get_main_queue(), ^(void){
[self animateAnnotationView:aV withAnnotationViews:annotationViews];
});
}
}
-(void)animateAnnotationView:(LLAnnotationView*)aV withAnnotationViews:(NSArray*)annotationViews{
#define kDurationBetweenShowUpAnimations 0.4
#define kLoopAnimationDuration 1
#define kAnimationDuration 0.4
// Initial animation
[UIView animateWithDuration:kAnimationDuration delay:kDurationBetweenShowUpAnimations*[annotationViews indexOfObject:aV]options:UIViewAnimationOptionCurveLinear animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.1, 1.1);
aV.alpha = 1.0;
}completion:^(BOOL finished){
[UIView animateWithDuration:kAnimationDuration/2 animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.0, 1.0);
aV.alpha = 0.9;
}completion:^(BOOL finished){
[UIView animateWithDuration:kAnimationDuration animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.1, 1.1);
aV.alpha = 1.0;
}completion:^(BOOL finished){
// **LOOP animation**
[UIView animateWithDuration:kLoopAnimationDuration delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.0, 1.0);
aV.alpha = 0.9;
}completion:^(BOOL finished){
}];
}];
}];
}];
}
Everything works as it should concerning the animation.
But when I try to select an annotation View, didSelectAnnotationView is rarely called.
I suspect that this should be thread related.
Does anyone have a clue what's going on??
Thank you.
Just found the solution. Add UIViewAnimationOptionAllowUserInteraction to the options of animateWithDuration :
[UIView animateWithDuration:kLoopAnimationDuration delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction ...
!!

automatically Move imageView on screen like L shape iOS

I am trying to move image like L shape in my iOS app.
I have tried this code but it is moving image only in one line that I don't want.
- (void)startApp {
UIImageView *imageToMove =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"man.jpg"]];
imageToMove.frame = CGRectMake(10, 10, 100, 100);
[self.view addSubview:imageToMove];
// Move the image
[self moveImage:imageToMove
duration:1.0
curve:UIViewAnimationCurveLinear
x:70.0
y:70.0];
}
- (void)moveImage:(UIImageView *)image
duration:(NSTimeInterval)duration
curve:(int)curve
x:(CGFloat)x
y:(CGFloat)y {
// Setup the animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
[UIView setAnimationBeginsFromCurrentState:YES];
// The transform matrix
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
image.transform = transform;
// Commit the changes
[UIView commitAnimations];
}
I would recommend something like this:
- (void)animateLikeL
{
[UIView animateWithDuration:1.5f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^{
self.yourImage.transform = CGAffineTransformMakeTranslation(0.0f, 10.0f);
} completion:^(BOOL finished){
if(finished == NO)
{
return;
}
[UIView animateWithDuration:1.5f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^{
self.yourImage.transform = CGAffineTransformMakeTranslation(10.0f, 10.0f);
} completion:^(BOOL finished){
if(finished == NO)
{
return;
}
self.yourImage.transform = CGAffineTransformIdentity;
[self animateLikeL];
}];
}];
}
Another attempt is to play arround with self.yourImage.center. Increase center.y to move the image down and then increase center.x to move it left. Hope this helps.
I did it like this: circle is a UIImage view in the interface builder size 70*70 and frame set at (10,10), then stick this code in:
- (void)viewDidAppear:(BOOL)animated {
[UIView animateWithDuration:1
delay:0
options:0
animations:^{
self.circle.frame = CGRectMake(10, 249, 70, 70);
}
completion:^(BOOL finished) {
[UIView animateWithDuration:1
delay:0
options:0
animations:^{
self.circle.frame = CGRectMake(150, 249, 70, 70);
}
completion:^(BOOL finished) {
NSLog(#"Complete");
}];
}];
}
I would just chain the animations.
[UIView animateWithDuration:duration/2 delay:0 options:curve animations:^{
CGAffineTransform transform = CGAffineTransformMakeTranslation(x,0);
image.transform = transform;
} completion:^(BOOL finished) {
[UIView animateWithDuration:duration/2 delay:0 options:curve animations:^{
CGAffineTransform transform = CGAffineTransformMakeTranslation(x,y);
image.transform = transform;
} completion:nil];
}];
This is what I have done......Thank you.
- (void)viewDidLoad
{
[super viewDidLoad];
[self startAppForFirstImg];
[self startAppForSecondImg];
}
//First Image coordinates.
- (void)startAppForFirstImg{
UIImageView *imageToMove =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"man.jpg"]];
imageToMove.frame = CGRectMake(180,280,100,100);
[self.view addSubview:imageToMove];
// Move the image
[self moveFirstImage:imageToMove duration:2.0
curve:UIViewAnimationCurveLinear x:0.0 y:-200.0];
}
-(void)moveFirstImage:(UIImageView *)image duration: (NSTimeInterval)duration
curve:(int)curve x:(CGFloat)x y:(CGFloat)y{
[UIView animateWithDuration:duration/2 delay:0 options:curve animations:^{
CGAffineTransform transform = CGAffineTransformMakeTranslation(0,y);
image.transform = transform;
}
completion:^(BOOL finished) {
[UIView animateWithDuration:duration/2 delay:0 options:curve animations:^{
CGAffineTransform transform = CGAffineTransformMakeTranslation(-70,-200);
image.transform = transform;
} completion:nil];
}];
}
//Second Image coordinates.
- (void)startAppForSecondImg{
UIImageView *imageToMove =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"man.jpg"]];
imageToMove.frame = CGRectMake(20,20,100,100);
[self.view addSubview:imageToMove];
// Move the image
[self moveSecondImage:imageToMove duration:2.0
curve:UIViewAnimationCurveLinear x:0.0 y:290.0];
}
-(void)moveSecondImage:(UIImageView *)image duration: (NSTimeInterval)duration
curve:(int)curve x:(CGFloat)x y:(CGFloat)y{
[UIView animateWithDuration:duration/2 delay:0 options:curve animations:^{
CGAffineTransform transform = CGAffineTransformMakeTranslation(0,y);
image.transform = transform;
}
completion:^(BOOL finished) {
[UIView animateWithDuration:duration/2 delay:0 options:curve animations:^{
CGAffineTransform transform = CGAffineTransformMakeTranslation(90,290);
image.transform = transform;
} completion:nil];
}];
}

When creating an animation to cause a UIImageView to go up and down (almost float) infinitely, how do I stop a pause at the end of the animation?

Here's the code I'm using to take a UIImageView and make it float up and down.
[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionRepeat animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.25 animations:^{
self.slider.transform = CGAffineTransformMakeTranslation(0, -5.0);
}];
[UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.5 animations:^{
self.slider.transform = CGAffineTransformMakeTranslation(0, 5.0);
}];
[UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
self.slider.transform = CGAffineTransformMakeTranslation(0, 0.0);
}];
} completion:^(BOOL finished) {
}];
However, it comes out looking like this with this delay after the animation ends and before it restarts.
How do I make it fluid?
I'm not sure what effect you're going for exactly, but I think this gives you something like your code does without the delay. I usually do this by animating a constraint, rather than using transforms. In this example, I've made an IBOutlet (topCon) to the constraint to the top of the view:
-(IBAction)floatView:(id)sender {
static int i= 1;
static float duration = .25;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
self.topCon.constant = self.topCon.constant - (5 * i);
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
i = (i == 1 || i == 2)? -2 : 2;
duration = 0.5;
[self floatView:self];
}];
}

Resources