#ios #xcode #view #gestures #label
Добрый день. Только начала изучать жесты в iOS, выполняю туториал http://www.appcoda.com/ios-gesture-recognizers/. Дошла до Pan Gesture Recognizer, и здесь возникла проблема: после присвоения меткам значений вертикальной и горизонтальной скорости, жест "ломается". UIVIew больше не перемещается плавно вместе с курсором мыши, а перепрыгивает в место, где остановился курсор мыши. Значения меток обновляются без проблем. Ниже приведен код, который реализует перемещение тестового вида: PanViewController.h @interface PanViewController : UIViewController @property (weak, nonatomic) IBOutlet UIView *testView; @property (weak, nonatomic) IBOutlet UILabel *horizontalVelocityLabel; @property (weak, nonatomic) IBOutlet UILabel *verticalVelocityLabel; @end PanViewController.m @interface PanViewController () - (void)moveViewWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer; @end @implementation PanViewController - (void)viewDidLoad { [super viewDidLoad]; UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveViewWithGestureRecognizer:)]; [self.testView addGestureRecognizer:panGestureRecognizer]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (void)moveViewWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer { CGPoint touchLocation = [panGestureRecognizer locationInView:self.view]; self.testView.center = touchLocation; После добавления следующих строк в последний метод и возникает проблема с неправильным выполнением жеста перетаскивания, хотя никаких ошибок не возникает: CGPoint velocity = [panGestureRecognizer velocityInView:self.view]; self.horizontalVelocityLabel.text = [NSString stringWithFormat:@"Horizontal Velocity: %.2f points/sec", velocity.x]; self.verticalVelocityLabel.text = [NSString stringWithFormat:@"Vertical Velocity: %.2f points/sec", velocity.y]; } Как мне исправить эту "поломку"? Очень хочется понять, что же я неправильно делаю, а не продолжать дальнейшее обучение, не разобравшись до конца с проблемой. Заранее спасибо.
Ответы
Ответ 1
Все потому, что при передвижении Вы ставите UIView в центр, а нужно расчитывать и устанавливать frame: - (void)moveViewWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer { //CGPoint touchLocation = [panGestureRecognizer locationInView:self.view]; //self.testView.center = touchLocation; CGPoint translation = [panGestureRecognizer translationInView:panGestureRecognizer.view]; CGRect newFrame = self.testView.frame; newFrame.origin.y = newFrame.origin.y + translation.y; newFrame.origin.x = newFrame.origin.x + translation.x; self.testView.frame = newFrame; [panGestureRecognizer setTranslation:CGPointZero inView:panGestureRecognizer.view]; CGPoint velocity = [panGestureRecognizer velocityInView:self.view]; self.horizontalVelocityLabel.text = [NSString stringWithFormat:@"Horizontal Velocity: %.2f points/sec", velocity.x]; self.verticalVelocityLabel.text = [NSString stringWithFormat:@"Vertical Velocity: %.2f points/sec", velocity.y]; } Этот код будет работать только если у Вас будет выключен Autolayout. Если же Autolayout включен, то для этого можно посмотреть вот это обсуждение https://stackoverflow.com/questions/16129988/ios-dragged-view-is-jumping-back-to-original-position-auto-layout-combined Вы можете посмотреть реализацию моего кода без autolayout: https://cloud.mail.ru/public/2g1Y/EC19pnX2PОтвет 2
Лучше не используйте frame или center, используйте для этого NSLayoutConstaint создайте @property (weak, nonatomic) IBOutlet NSLayoutConstaint *testViewLeft; дальше двигайте ее: self.testViewLeft.constant = newValue; [self.view layoutIfNeeded]; чтобы это происходило с анимацией, поместите layoutIfNeeded() в блок анимации [UIView animateWithDuration: 0.1 animations: ^{ [self.view layoutIfNeeded]; } completion: nil]; сохраните offset точки начала жеста от края view, это поможет сделать движение более плавным вначале @property (nonatomic) CGFloat panOffset; к тому же в action проверяйте состояние жеста: - (void)panGestureStateChanged:(UIPanGestureRecognizer *)sender { switch (sender.state) { case UIGestureRecognizerStateBegan: self.panOffset = sender.locationInView(contentContainerView).x break; case UIGestureRecognizerStateChanged: CGFloat touchPoint = [sender locationInView:view]; CGFloat newConstant = touchPoint.x - offset; self.testViewLeft.constant = newConstant; [UIView animateWithDuration:0.03 animations:^{ [self.view layoutIfNeeded]; } completion: nil]; break; case UIGestureRecognizerStateEnded: panOffset = 0; break; default: break; } } еще полезным будет стать UIGestureRecognizerDelegate и реализовать метод, чтобы контроливать когда следует начинать жест, а когда нет: - (BOOL)gestureRecognizerShouldBegin(UIGestureRecognizer *)gestureRecognizer { if (gestureRecognizer == self.myPanGesture) { return (someGestureBeginConditions > 0); } return true; }
Комментариев нет:
Отправить комментарий