Страницы

Поиск по вопросам

суббота, 11 апреля 2020 г.

Реализация перемещения тестового UIView и установка текста метки

#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; }

Комментариев нет:

Отправить комментарий