Почему существует задержка при перемещении объекта с использованием UIPanGestureRecognizer
Я перемещаю объект UIView с помощью UIPanGestureRecognizer - насколько сильно я перетаскиваю палец на экран, так что я перемещаю представление в том же направлении (только в X - влево или вправо, Y не меняется). Он отлично работает, но с (очень заметной) задержкой.
Вот метод, который обрабатывает событие UIPanGestureRecognizer:
-(void)movePages:(UIPanGestureRecognizer *)sender
{
if(switchingMode == 1){
if([sender state] == UIGestureRecognizerStateBegan){
fingerStartPosition = [sender locationInView:self.view].x;
viewStartPosition = [[viewControllers objectAtIndex:activeViewControllerIndex] view].center;
}
[[[[viewControllers objectAtIndex:activeViewControllerIndex] view] layer] setPosition:CGPointMake(viewStartPosition.x - (fingerStartPosition - [sender locationInView:self.view].x) , viewStartPosition.y)];
}
}
Я попытался установить положение представления, используя его слой, я также попытался установить фрейм, используя анимацию с разной продолжительностью, но все было одинаково. Любая идея, почему происходит эта задержка?
Ответы
Ответ 1
Используйте UILongPressGestureRecognizer
и установите для параметра minimumPressDuration
значение 0.0
. Это мгновенно распознается, и вы получаете все те же обновления, в том числе UIGestureRecognizerStateChanged
с обновленным местоположением.
Ответ 2
Функция GestureRecognizer не может быть уверенной, если это жест, когда вы переместили палец на несколько пикселей. Я не знаю точное значение толерантности, но именно поэтому вы чувствуете задержку.
Документация:
Пиннинг жест непрерывный. Это начинается, когда минимальное количество пальцев разрешено перемещаться достаточно, чтобы считаться кастрюлем.
Если вам требуется мгновенное перемещение, вам, вероятно, нужно построить свою собственную логику, используя touchesMoved:
.
Другой подход может заключаться в анимировании первой признанной точки. Но это не устраняет задержку.
Для этого подхода вы можете взглянуть на JDDroppableView на github.
Ответ 3
Я обнаружил, что он быстрее реагирует, если вы используете только обычные касанияBegan, Moved и Ended. Я даже подклассифицировал UIGestureRecognizer, и у него все еще было отставание на жесте панорамирования. Несмотря на то, что прикосновенияBegan в UIGestureRecognizer будут срабатывать вовремя, изменение состояния займет половину секунды, чтобы изменить его состояние... Кажется, что быстрее использовать простой старый TouchesBegan, особенно если вы много CPU./p >
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
if touches.count == 1
{
initialTouchLocation = (touches.first?.locationInView(self).x)!
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)
{
if touches.count == 1
{
let locationInView = touches.first?.locationInView(self)
if !thresholdHit
{
//this is the threshold for x movement in order to trigger the panning...
if abs(initialTouchLocation - locationInView!.x) > 1
{
thresholdHit = true
}
}
else
{
if (self.frame.width != CGFloat(screenSize))
{
let panDelta = initialTouchLocation - locationInView!.x
}
}
}
}