iPhone: как повернуть UIImageview влево или вправо?

Я хочу повернуть UIImageView следующим образом: если я удерживаю изображение и перемещаю палец влево, то изображение должно вращаться вправо (и наоборот).

Вот ссылка Баланс


person Rahul Vyas    schedule 04.02.2010    source источник


Ответы (2)


Я возился с этим в прошлом году. Это оказалось сложнее, чем я думал. IIRC, этот маленький класс сделал то, что вы хотели. Это UIButtonSubclass, который отображает изображение и реагирует на щелчки и перетаскивания. Обратите внимание, что это просто скретч-код. Он не выполняет никакого управления памятью, очистки и т. Д.

#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
person TechZen    schedule 04.02.2010
comment
Еще один пользовательский класс. Это должно было создать эффект покачивания, как на трамплине, когда вы удаляете приложение. Это не имеет отношения к вашей проблеме. Вы хотите взглянуть на методы rotateRight и rotateLeft, а также на методы самокасания. Имейте в виду, что эти методы просто поворачивают визуальное отображение представления и не влияют на фактическое изображение, отображаемое в представлении, т.е. если вы сохраняете представление или компонуете его в другом представлении, вы получаете исходную ориентацию изображения. - person TechZen; 05.02.2010
comment
Хорошо, теперь скажите мне, что я создаю мяч и отправляю его сверху вниз. Для этого я сделал 3 изображения (например, 3 мяча), теперь я случайным образом выбираю мячи при создании, так как я могу определить, какой мяч был пересекались? - person Rahul Vyas; 05.02.2010

У вас может быть ivar в вашем контроллере для отслеживания начала перетаскивания. Когда вы получите событие «приземление», сохраните начальную точку. Когда вы получаете события «перемещено касанием», рассчитайте расстояние от текущей точки до сохраненной точки. Евклидово расстояние между ними может дать вам вращение (знак, указывающий, в каком направлении вращаться). Соответствующим образом масштабируйте поворот (т. е., возможно, половина ширины представления эквивалентна 180 градусам) и установите поворот преобразования изображения.

person gavinb    schedule 04.02.2010
comment
У меня нет существующего кода для этого. Я просто объяснил, как я начну решать проблему. Вы должны быть в состоянии перевести приведенное выше описание в код без особых трудностей! Развлекайся... - person gavinb; 05.02.2010
comment
Хорошо, я получил половину этого, но проблема в том, что ImageView получает ZigZagged при вращении. Как это решить? также он вращается только влево или вправо, когда он идет влево или вправо только от начальной точки. Я имею в виду, что я просто хочу, чтобы он всегда вращался, когда я перемещаю изображение влево или вправо. Также один вопрос от вас, вы видели приведенную выше ссылку. Я хотите, чтобы это было именно так, пожалуйста, посмотрите и направьте в правильном направлении - person Rahul Vyas; 11.02.2010
comment
Что вы имеете в виду, говоря, что изображение становится зигзагообразным? Если вы хотите иметь кумулятивный эффект поворота, вам нужно добавить ivar для хранения предыдущего поворота и добавить его к текущему повороту, когда пользователь перетаскивает из начальной точки. А на какую ссылку вы ссылаетесь? Я не вижу? - person gavinb; 12.02.2010
comment
я добавил ссылку, пожалуйста, посмотрите - person Rahul Vyas; 13.02.2010