Анимация iPhone / Какао, имеющая эффект, я не понимаю - PullRequest
0 голосов
/ 19 июля 2009

Я создал базовый слайдер разблокировки, который вы используете для разблокировки iPhone.

В моей функции touchesEnded я использую анимацию, чтобы переместить ползунок обратно к дому.

В первый раз, когда пользователь перемещает ползунок (и фактически не доходит до конца, чтобы разблокировать), анимация работает нормально, и ползунок возвращается к дому.

Однако в следующий раз, когда пользователь пытается переместить ползунок (и вызывается touchesMoved), ползунок выталкивается за пределы экрана (влево) на величину, которую он передвинул перед этим ползунком.

Итак, что происходит?

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  self.dragging = NO;
  self.startX = 0; 
  [UIView beginAnimations:nil context:nil];
  [UIView setAnimationDuration:0.5];
  self.unlock.frame = CGRectMake(0, 0, 75, 35);
  [UIView commitAnimations];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  if (!self.dragging ) { return; }
  UITouch *touch = [[event allTouches] anyObject];
  CGPoint point = [touch locationInView:self];
  int offset = point.x - self.startX;
  NSLog(@"%i", offset);
  if (offset > (LENGTH-SIZE)) {
    offset = (LENGTH-SIZE);
  }
  CGAffineTransform myTransform = CGAffineTransformMakeTranslation(offset, 0.0);
  [self.unlock setTransform:myTransform];
  if (point.x >= (LENGTH-(SIZE-self.startX))) {
    NSLog(@"Slider reached end");
    [self.sliderView removeFromSuperview];
  }
}

EDIT

Вот рабочая функция, немного исправленная, хотя она могла бы быть и лучше (благодаря паре ответов на вопросы по SO от одного хакера). Я собираюсь опубликовать полный модуль в блоге, так как нет стандартного виджета:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

  if (!self.dragging ) { return; }

  UITouch *touch = [[event allTouches] anyObject];
  CGPoint point = [touch locationInView:self];  

  if (point.x >= (LENGTH-(SIZE-self.startX))) {
    NSLog(@"Slider reached end");
    [self.sliderView removeFromSuperview];
  }

  // offset based on where the user clicked the slider
  int offset = point.x - self.startX;
  if (offset > (LENGTH-SIZE)) {
    offset = (LENGTH-SIZE);
  }

  //move the slider
  CGRect oldFrame = self.unlock.frame;
  CGRect newFrame = CGRectMake(self.frame.origin.x+offset, self.frame.origin.y-5, oldFrame.size.width, oldFrame.size.height);
  self.unlock.frame = newFrame; 
}

Ответы [ 2 ]

1 голос
/ 19 июля 2009

В вашем предыдущем вопросе я не осознавал, что вы перемещали ползунок, изменяя его трансформацию. Смешение движения путем изменения его кадра и преобразования будет умеренно сложным.

Может быть, вы могли бы попытаться сделать что-то более похожее на это:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  if (!self.dragging ) { return; }
  UITouch *touch = [[event allTouches] anyObject];
  CGPoint point = [touch locationInView:self];
  int offset = point.x - self.startX;
  NSLog(@"%i", offset);
  if (offset > (LENGTH-SIZE)) {
    offset = (LENGTH-SIZE);
  }

  CGRect oldFrame = self.frame;
  CGRect newFrame = CGRectMake(oldFrame.origin.x+offset, oldFrame.origin.y, oldFrame.size.width, oldFrame.size.height);
  self.frame = newFrame;

  if (point.x >= (LENGTH-(SIZE-self.startX))) {
    NSLog(@"Slider reached end");
    [self.sliderView removeFromSuperview];
  }
}

Это перемещает ползунок, изменяя его кадр, а не его перевод, что должно заставить его лучше взаимодействовать с анимацией возврата назад. В качестве альтернативы, вместо сброса кадра в неявном аниматоре вы можете сбросить перевод там.

0 голосов
/ 19 июля 2009

Вам нужно сбросить преобразование вида в вашем касании. Обработчик закруглений:

[self.unlock setTransform:CGAffineTransformIdentity];

Попробуйте вместо анимации свойства frame.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...