views:

1207

answers:

2

Hello all,

I want to rotate an UIImageView in the following manner: If I hold the imageview and move the finger to left, then the imageview should rotate to the right (and vice-versa.)

Here is the link Balance

A: 

You could have an ivar in your controller for tracking the start of the drag. When you get a 'touch down' event, save the starting point. As you get 'touch moved' events, calculate the distance from the current point to the saved point. The Euclidean distance between the two can give you the rotation (the sign telling you which direction to rotate). Scale the rotation appropriately (ie. perhaps half the view width is equivalent to 180deg), and set the rotation of the image's transform.

gavinb
can you post some sample?
Rahul Vyas
I don't have any existing code for this. I just explained how I would start tackling the problem. You should be able to translate the description above into code without too much difficulty! Have fun...
gavinb
ok i got half of it but hte problem is ImageView is getting ZigZagged while rotating.How to solve this? also it only rotate left or right when it goes left or right from begining point only.I mean i just want it rotate always when i move Imageview it to left or right.Also one question from you that have you seen the above link.I want it exactly like that please have a look and guide in right direction
Rahul Vyas
What do you mean by the image getting "zig-zagged"? If you want to have a cumulative rotation effect, you need to add an ivar to store the previous rotation, and add this to the current rotation, as the user drags from the beginning point. And to which link are you referring? I don't see any?
gavinb
i have added the link please take a look
Rahul Vyas
A: 

I fiddle with this last year. It proved more complex than I thought it would. IIRC, this little class did what you wanted. It's a UIButtonSubclass that displays an image and responds to clicks and drags. Note that this is just scratch code. It doesn't do any memory management, cleanup etc.

#import <UIKit/UIKit.h>
#import "BackgroundImageButton.h"
#import "WiggleImageView.h"

@interface StickerButton : UIButton {
    //ivars used to control selection animaiton
    CGAffineTransform startTransform;
    BOOL currentlyAnimating;
    BOOL shouldAnimate; 
    //ivars to handle touches and control events
    BOOL wasDrag;
    BOOL wasTouchDown;
  WiggleImageView * imgView;
}
//ivars used to control selection animaiton
@property CGAffineTransform startTransform;
@property(nonatomic, retain)  WiggleImageView *imgView;
@property BOOL currentlyAnimating;
@property BOOL shouldAnimate;
//ivars to handle touches and control events
@property BOOL wasDrag;
@property BOOL wasTouchDown;


#pragma mark Initialization
-(id) initWithImage:(UIImage *)anImage atCenterPoint:(CGPoint) centerPoint;

#pragma mark Selection Animation Methods
-(void) animateSelection;
-(void) animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context;

#pragma mark Self Touch Methods  //not as dirty as it sounds.
-(void) touchDragSelf:(id)sender withEvent:(UIEvent *) theEvent;
-(void) touchDownSelf:(id)sender withEvent:(UIEvent *) theEvent;
-(void) touchUpSelf:(id)sender withEvent:(UIEvent *) theEvent;

#pragma mark Graphic Edit Methods
-(void) rotateRight;
-(void) rotateLeft;
-(void) scaleUp;
-(void) scaleDown;
-(void) select;
-(void) deselect;
-(void) translateMoveByX:(CGFloat) dx andY:(CGFloat) dy; //used by self to account for translated coordinates
-(void) frameMoveByX:(CGFloat) dx andY:(CGFloat) dy; //used by external to move frame in superview    
@end

#import "StickerButton.h"

@implementation StickerButton
@synthesize startTransform;
@synthesize currentlyAnimating;
@synthesize shouldAnimate;
@synthesize wasDrag;
@synthesize wasTouchDown;
@synthesize imgView;


#pragma mark Initialization
- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        startTransform=self.transform;
        currentlyAnimating=NO;
        shouldAnimate=NO;
        wasDrag=NO;
        wasTouchDown=NO;
        self.adjustsImageWhenDisabled=NO;
        self.adjustsImageWhenHighlighted=NO;
        self.showsTouchWhenHighlighted=NO;
        [self addTarget:self action:@selector(touchDownSelf:withEvent:) forControlEvents:UIControlEventTouchDown];
        [self addTarget:self action:@selector(touchDragSelf:withEvent:) forControlEvents:UIControlEventTouchDragInside];
        [self addTarget:self action:@selector(touchUpSelf:withEvent:) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
}

-(id) initWithImage:(UIImage *)anImage atCenterPoint:(CGPoint) centerPoint{
    CGFloat xOrigin,yOrigin;
    xOrigin=centerPoint.x-(anImage.size.width/2);
    yOrigin=centerPoint.y-(anImage.size.height/2);
    [self initWithFrame:CGRectMake(xOrigin, yOrigin, anImage.size.width, anImage.size.height)];
    WiggleImageView *w=[[WiggleImageView alloc] initWithFrame:self.bounds];
    imgView=w;
    imgView.image=anImage;
    [self addSubview:imgView];
    return self;
}//------------------------------------initWithImage:atCenterPoint:------------------------------------



#pragma mark Selection Animation Methods
-(void) animateSelectedThrob{
    if (!currentlyAnimating) {
        NSLog(@"animating");
        currentlyAnimating=YES;
        //startTransform=self.transform; //this has to be saved to prevent some kind of rounding error from gradually rotating the view
        [UIView beginAnimations:@"selectionAnimation" context:nil];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDuration:0.1];
        [UIView setAnimationRepeatCount:1];
        [UIView setAnimationRepeatAutoreverses:YES];
        self.transform=CGAffineTransformScale(self.transform, 1.1, 1.1);
        [UIView commitAnimations];
    } 
}//-------------------------------------(void) animateSelectedThrob------------------------------------


-(void) animateSelection{
    if (!currentlyAnimating) {
        //NSLog(@"animating");
        currentlyAnimating=YES;
        startTransform=self.transform; //this has to be saved to prevent some kind of rounding error from gradually rotating the view
        [UIView beginAnimations:@"selectionAnimation" context:nil];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDuration:0.1];
        [UIView setAnimationRepeatCount:2];
        [UIView setAnimationRepeatAutoreverses:YES];
        self.transform=CGAffineTransformRotate(self.transform, (2 * M_PI / 180) );
        [UIView commitAnimations];
    } 

}//-------------------------------------(void) animateSelection------------------------------------

-(void) animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
    self.transform=startTransform;
    currentlyAnimating=NO;
    if (shouldAnimate) {

        [self animateSelection];
    }   
}//------------------------------------animationDidStop:finished:context:------------------------------------

#pragma mark Self Touch Methods

-(void) touchDownSelf:(id)sender withEvent:(UIEvent *) theEvent{
    NSLog(@"touchDownSelf");
    wasTouchDown=YES;
    shouldAnimate=NO;
}//------------------------------------touchDownSelf:withEvent:------------------------------------

-(void) touchDragSelf:(id)sender withEvent:(UIEvent *) theEvent{
    NSLog(@"touchDragSelf");
    if ([[theEvent touchesForView:self] count]==1) {
        UITouch *t=[[theEvent touchesForView:self] anyObject];
        CGPoint l,p;
        l=[t locationInView:self];
        p=[t previousLocationInView:self];
        [self translateMoveByX:(l.x-p.x) andY:(l.y-p.y)];
        wasDrag=YES;        
    }

}//------------------------------------touchDragSelf:withEvent:------------------------------------

-(void) touchUpSelf:(id)sender withEvent:(UIEvent *) theEvent{
    NSLog(@"touchUpSelf");
//  if (!wasDrag && wasTouchDown) {
//      [self select];
//  }
    if (wasTouchDown) {
        [self select];
    }
    wasDrag=NO;
    wasTouchDown=NO;
}//------------------------------------touchUpSelf:withEvent:------------------------------------

#pragma mark Graphic Edit Methods 
-(void) rotateRight{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.1];
    [UIView setAnimationBeginsFromCurrentState:YES];
    self.transform=CGAffineTransformRotate(self.transform, (M_PI / 180) );
    [UIView commitAnimations];  
}//-------------------------------------(void) rotateRight------------------------------------

-(void) rotateLeft{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.1];
    [UIView setAnimationBeginsFromCurrentState:YES];
    self.transform=CGAffineTransformRotate(self.transform, (-1*M_PI / 180) );
    [UIView commitAnimations];
}//-------------------------------------(void) rotateLeft------------------------------------

-(void) scaleUp{
    //todo add variable to track total scale so it doesn't get to big and cause problems
    shouldAnimate=NO;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.1];
    [UIView setAnimationBeginsFromCurrentState:YES];
    self.transform=CGAffineTransformScale(self.transform, 1.1, 1.1);
    [UIView commitAnimations];
    startTransform=self.transform;
}//-------------------------------------(void) scaleUp------------------------------------

-(void) scaleDown{
    //todo add variable to track total scale so it doesn't get to small and cause problems
    shouldAnimate=NO;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.1];
    [UIView setAnimationBeginsFromCurrentState:YES];
    self.transform=CGAffineTransformScale(self.transform, 0.9, 0.9);
    [UIView commitAnimations];
    startTransform=self.transform;
}//-------------------------------------(void) scaleDown------------------------------------

-(void) select{ 
    [self animateSelectedThrob];
    imgView.shouldWiggle=YES;
}
//-------------------------------------(void) select------------------------------------

-(void) deselect{
    imgView.shouldWiggle=NO;
}

-(void) translateMoveByX:(CGFloat) dx andY:(CGFloat) dy{ //necessary for all points that orignate within the transformed view
    NSLog(@"dx=%f,dy=%f",dx,dy);
    shouldAnimate=NO;
    self.transform=CGAffineTransformTranslate(self.transform, dx,dy);
    startTransform=self.transform;
}//------------------------------------translateMoveByX:andY:------------------------------------

-(void) frameMoveByX:(CGFloat) dx andY:(CGFloat) dy{ //necessary for all points that originate outside the transformed view

    self.frame=CGRectMake(self.frame.origin.x+dx, self.frame.origin.y+dy, self.frame.size.width, self.frame.size.height);
}//------------------------------------frameMoveByX:andY:------------------------------------
- (void)drawRect:(CGRect)rect {
    // Drawing code
}

- (void)dealloc {
    [super dealloc];
}

@end
TechZen
what is WiggleImageView?
Rahul Vyas
Another custom class. It was meant to create a wiggle effect like on the springboard when you remove an app. It's not relevant to your problem. You want to look at the rotateRight and rotateLeft methods and the self touch methods. Be aware, these methods just rotate the visual display of the view and do not affect the actual image the view displays i.e. if you save the view or composite it on another view, you get the images original orientation.
TechZen
ok now tell me that i am creating a ball and sending it from the top of screen to bottom.For this i haev taken 3 images(like 3 balls) now i am choosing randomly the balls when creating so how do i detect which ball was intersected?
Rahul Vyas