Установка точки привязки для слоя UIView

У меня есть подкласс UIView, который я хочу иметь возможность перемещаться в его суперпредставлении. Когда пользователь касается UIView где-то за пределами self.center но внутри self.bounds он "прыгает", потому что я добавляю новое местоположение в self.center чтобы добиться фактического движения. Чтобы избежать такого поведения, я пытаюсь установить опорную точку, которая позволяет пользователю захватывать и перетаскивать вид в любом месте в пределах его границ.

Моя проблема в том, что когда я вычисляю новую опорную точку (как показано в приведенном ниже коде), ничего не происходит, вид вообще не меняет положение. С другой стороны, если я установлю опорную точку на предварительно рассчитанную точку, я смогу переместить вид (но тогда, конечно, он "скачет" в предварительно рассчитанную точку). Почему это не работает, как ожидалось?

Благодарю.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
    // Only support single touches, anyObject retrieves only one touch
    UITouch *touch = [touches anyObject];
    CGPoint locationInView = [touch locationInView:self];

    // New location is somewhere within the superview
    CGPoint locationInSuperview = [touch locationInView:self.superview];

    // Set an anchorpoint that acts as starting point for the move
    // Doesn't work!
    self.layer.anchorPoint = CGPointMake(locationInView.x / self.bounds.size.width, locationInView.y / self.bounds.size.height);
    // Does work!
    self.layer.anchorPoint = CGPointMake(0.01, 0.0181818);

    // Move to new location
    self.center = locationInSuperview;
}

2 ответа

Решение

Как указал Крис Ван Баел, вам нужно будет выполнить вычисления опорных точек в touchsBegan:withEvent: метод, чтобы не отрицать движение. Кроме того, так как изменение слоя anchorPoint переместит начальную позицию представления, вы должны добавить смещение к представлению center указать, чтобы избежать "прыжка" после первого касания.

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

Возможно, что-то вроде этого:

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

    UITouch *touch = [touches anyObject];
    CGPoint locationInView = [touch locationInView:self];
    CGPoint locationInSuperview = [touch locationInView:self.superview];

    self.layer.anchorPoint = CGPointMake(locationInView.x / self.frame.size.width, locationInView.y / self.frame.size.height);
    self.center = locationInSuperview;
}

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

    UITouch *touch = [touches anyObject];
    CGPoint locationInSuperview = [touch locationInView:self.superview];

    self.center = locationInSuperview;
}

Больше информации о anchorPoint Это из документов Apple и аналогичного вопроса SO, на который я ссылался здесь.

Вы должны обновить anchorpoint только на TouchBegin. Если вы все время пересчитываете (TouchMoved), логично, что подпредставление не перемещается.

Другие вопросы по тегам