2010-11-15 3 views
1

Я пытаюсь реализовать колесо выбора в приложении iphone. У меня есть колесо для отслеживания пальцев пользователя, но теперь по какой-то причине, когда пользователь прикасается к экрану, колесо прыгает, так что один и тот же участок колеса отслеживает палец каждый раз.iPhone - Отслеживание пальца пальца переходит в ту же начальную позицию?

Как бы это сделать, чтобы колесо вращалось, как пользователь, перетаскивая его из любой точки?

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
NSSet *allTouches = [event allTouches]; 

int tInput = [allTouches count]-1; 

UITouch *touch =[[allTouches allObjects] objectAtIndex:tInput]; 
CGPoint location = [touch locationInView:self.view]; 
float theAngle = atan2(location.y-imageX.center.y, location.x-imageX.center.x); 

CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(theAngle); 
imageX.transform = cgaRotate; 

}

Любое предложение?

ответ

3

Право - это имеет смысл - это действительно то, что делает ваш код.

Что нужно добавить - это начальное значение, в котором вы начали свое перетаскивание как относительное вращение - или отслеживаете свой последний поворот.

Ниже показан очень продуманный способ - но это должно помочь получить точную точку.

@interface UntitledViewController : UIViewController { 
     CGPoint firstLoc; 
     UILabel * fred; 
     double angle; 
} 
@property (assign) CGPoint firstLoc; 
@property (retain) UILabel * fred; 

@implementation UntitledViewController 
@synthesize fred,firstLoc; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.fred = [[UILabel alloc] initWithFrame:CGRectMake(100,100,100,100)]; 
    fred.text = @"Fred!"; fred.textAlignment = UITextAlignmentCenter; 
    [self.view addSubview:fred]; 

    angle = 0; // we aint have rotated just yet... 
}; 

// make sure we get them drag events. 
- (BOOL)isFirstResponder { return YES; } 

-(void)handleObject:(NSSet *)touches 
      withEvent:(UIEvent *)event 
      isLast:(BOOL)lst 
{ 
    UITouch *touch =[[[event allTouches] allObjects] lastObject]; 
    CGPoint curLoc = [touch locationInView:self.view]; 

    float fromAngle = atan2(firstLoc.y-fred.center.y, 
          firstLoc.x-fred.center.x); 
    float toAngle = atan2(curLoc.y-fred.center.y, 
          curLoc.x-fred.center.x); 

    // So the angle to rotate to is relative to our current angle and the 
    // angle through which our finger moved (to-from) 
    float newAngle = angle + (toAngle - fromAngle); 

    CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(newAngle); 
    fred.transform = cgaRotate; 

    // we only 'save' the current angle when we're done with the drag. 
    // 
    if (lst) 
     angle = newAngle; 
    } 

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch =[[[event allTouches] allObjects] lastObject]; 

    // capture where we started - so we can later work out the 
    // rotation relative to this point. 
    // 
    firstLoc = [touch locationInView:self.view]; 
}; 


-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self handleObject:touches withEvent:event isLast:NO]; 
}; 

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self handleObject:touches withEvent:event isLast:YES]; 
} 

Очевидно, что вы можете сделать это гораздо более элегантно - и выше пропускает немного 0 .. 2xPI укупорки вам нужно.

+0

Ты потрясающий !!!!! Удивительно!! Спасибо огромное! –

+0

Большое вам спасибо за вашу помощь, но у меня есть еще одна вещь, использующая этот метод, кажется, мешает мне обнаруживать штрихи в UIImageView (Circle)? В методе начатых шагов я добавляю этот код, чтобы зафиксировать местоположение касания и сравнить с моим изображением, но он, похоже, не срабатывает? CGPoint location = [touch locationInView: touch.view.superview]; \t если ([touch view] == imageOne) { \t imageHolder = coinOne; } любые предложения относительно того, почему это так? –

+0

Aye - просто отключите взаимодействие с пользователем во всех других представлениях - так что все взаимодействия видны каким бы то ни было UIView, на котором вы выполняете обнаружение перетаскивания. –

0

Потому что сам вид по-прежнему старый. Вы можете извлечь файл примера почтового индекса в:

http://bynomial.com/blog/?p=77 

и PuttyView.m изменить:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
.... 
else { 
    self.center = CGPointMake(self.center.x + touchPoint.x - touchStart.x, 
          self.center.y + touchPoint.y - touchStart.y); 

в

else { 
    NSSet *allTouches = [event allTouches]; 

    int tInput = [allTouches count]-1; 

    UITouch *touch =[[allTouches allObjects] objectAtIndex:tInput]; 
    CGPoint location = [touch locationInView:self]; 
    float theAngle = atan2(location.y-self.center.y, location.x-self.center.x); 

    CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(theAngle); 
    self.transform = cgaRotate; 

}

где вы, таким образом, остаться в пределах вида и его относительного угла. Альтернативно - в вашем коде - сохраняйте относительный угол.

+0

то, что вы предложили, не работает, если что-то это нарушает отслеживание пользователей от 1 до 1, когда объект вращается при меньшем количестве радианов. Пройдя мимо определенной точки вращения, объект переворачивается, чтобы выровняться к другой точке. –

+0

Не уверен, если я пойму первый пункт. Последняя точка действительно правильная - atan2() с этой дельтой, которая дает вам наименьшее вращение, под которым объект должен вращаться, чтобы выровнять его с этим вектором - следовательно, щелчок. –

+0

Первый пункт - исходный код, который я поставляю, уже хорошо отслеживает палец, но когда пользователь нажимает палец на экран, изображение будет автоматически выровняться так, чтобы точка 90 градусов на изображении была фиксированной точкой, которая отслеживает палец. Реализация вашего кода делает так, что при отслеживании пальца пользователя для каждого полного поворота пальцы пользователя завершаются, изображение поворачивается только на 3/5 оборота? а также flipping ... –

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