Я пытаюсь дать пользователю возможность перемещать UILabel
вверх и вниз по представлению, присоединив UIPanGestureRecognizer
к UILabel
и впоследствии изменив константу ограничения с UILabel
на верхнюю часть его представления. Таким образом, в основном, если распознаватель жестов обнаруживает, что они перемещаются вниз на 12 пунктов, переместите константу ограничения на 12 пунктов, чтобы переместить UILabel
.
Однако я хочу, чтобы они не двигались дальше, когда они достигают определенной вертикальной точки (как слишком высокой, так и слишком низкой). Я мог бы просто проверить перевод жеста панорамирования, но мой UILabel
может состоять из любого количества строк, поэтому, если это пять строк вместо одной, очевидно, что его нельзя панорамировать так далеко, поэтому я не могу полагаться на перевод жеста панорамирования, я должен учитывать размер метки.
Итак, я начал отслеживать его кадр, и он работает хорошо, но в моей реализации есть раздражающий результат: если они полностью панорамируются до нижнего предела, они должны панорамироваться очень далеко назад, прежде чем UILabel
«догоняет» и идет с ним ( хотя такой проблемы не существует, когда они достигают верхней границы). По сути, они перемещаются вниз до нижнего предела, а когда они перемещаются обратно вверх (все это выполняется одним и тем же жестом), он на мгновение «залипает», пока они не перемещаются достаточно далеко вверх, а затем подпрыгивают пальцем вверх.
Вот код, который я использую для этого:
- (void)textLabelPanned:(UIPanGestureRecognizer *)panGestureRecognizer {
if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) {
_textDistanceFromTopBeforeMove = self.textToReadLabelPositionFromTopConstraint.constant;
}
else if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
NSNumber *textDistanceFromTop = @(self.textToReadLabelPositionFromTopConstraint.constant);
[[NSUserDefaults standardUserDefaults] setObject:textDistanceFromTop forKey:@"TextDistanceFromTop"];
}
else {
if (CGRectGetMinY(self.textToReadLabel.frame) >= [UIScreen mainScreen].bounds.origin.y + CLOSEST_TEXT_DISTANCE_TO_TOP && CGRectGetMaxY(self.textToReadLabel.frame) <= [UIScreen mainScreen].bounds.size.height - CLOSEST_TEXT_DISTANCE_TO_BOTTOM) {
self.textToReadLabelPositionFromTopConstraint.constant = _textDistanceFromTopBeforeMove + [panGestureRecognizer translationInView:self.mainView].y;
}
else if ([panGestureRecognizer translationInView:self.mainView].y > 0) {
if (CGRectGetMaxY(self.textToReadLabel.frame) + _textDistanceFromTopBeforeMove + [panGestureRecognizer translationInView:self.mainView].y < [UIScreen mainScreen].bounds.size.height - CLOSEST_TEXT_DISTANCE_TO_BOTTOM) {
self.textToReadLabelPositionFromTopConstraint.constant = _textDistanceFromTopBeforeMove + [panGestureRecognizer translationInView:self.mainView].y;
}
}
else if ([panGestureRecognizer translationInView:self.mainView].y < 0) {
if (CGRectGetMinY(self.textToReadLabel.frame) + _textDistanceFromTopBeforeMove + [panGestureRecognizer translationInView:self.mainView].y > [UIScreen mainScreen].bounds.origin.y + CLOSEST_TEXT_DISTANCE_TO_TOP) {
self.textToReadLabelPositionFromTopConstraint.constant = _textDistanceFromTopBeforeMove + [panGestureRecognizer translationInView:self.mainView].y;
}
}
// If one of the options views are present and the user pans really low, hide the options as to allow the user to see where they're panning
if (_inSpeedChangingMode) {
if (CGRectGetMaxY(self.textToReadLabel.frame) > CGRectGetMinY(self.progressBar.frame) - 10) {
[self showWordOptions:nil];
}
}
else if (_inTextChangingMode) {
if (CGRectGetMaxY(self.textToReadLabel.frame) > CGRectGetMinY(self.progressBar.frame) - 10) {
[self showTextOptions:nil];
}
}
}
}
Что именно я делаю неправильно, из-за чего он «залипает»? И, возможно, есть лучший способ сделать это?