2010-02-04 5 views

ответ

1

Я играю с этим в прошлом году. Это оказалось более сложным, чем я думал. 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 
+1

Что такое WiggleImageView? –

+0

Другой пользовательский класс. Он предназначен для создания эффекта «покачивания», как на трамплине, когда вы удаляете приложение. Это не относится к вашей проблеме. Вы хотите посмотреть методы rotateRight и rotateLeft и методы самонастройки. Имейте в виду, что эти методы просто поворачивают визуальный дисплей представления и не влияют на фактическое изображение, отображаемое на экране, т. Е. Если вы сохраняете представление или составьте его на другом представлении, вы получаете исходную ориентацию изображений. – TechZen

+0

ok теперь скажите мне, что я создаю шар и отправляю его с верхней части экрана на дно. Для этого я haev взял 3 изображения (например, 3 шара), теперь я выбираю случайным образом шары при создании так, как я могу определить, какой мяч был пересечен? –

0

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

+0

Можете ли вы разместить образец? –

+0

У меня нет кода для этого. Я только что объяснил, как я начну решать проблему. Вы должны уметь переводить описание выше в код без особых трудностей! Получайте удовольствие ... – gavinb

+0

ОК, я получил половину этого, но проблема hte - ImageView получает ZigZagged во время вращения. Как решить это? также он вращается только влево или вправо, когда он идет влево или вправо от начальной точки. Я имею в виду, что просто хочу, чтобы он вращался всегда, когда я перемещаю изображение влево или вправо. Также один вопрос от вас, который вы видели выше. хотите это точно так, пожалуйста, посмотрите и направьте в правильном направлении –

Смежные вопросы