2015-05-16 5 views
1

Мой контроллер контейнера имеет жест панорамирования края экрана, чтобы изменить вид. Код для панорамирования мнения выглядит следующим образом:UIScreenEdgeRecognizerGesture гладкий, как сафари

func changeView(recognizer: UIScreenEdgePanGestureRecognizer) { 

    println("INITIAL: \(recognizer.translationInView(view))") 

    if recognizer.state == .Began { 
     // Create and configure the view 

     println("BEGAN: \(recognizer.translationInView(view))") 
    } 

    if recognizer.state == .Changed { 
     println("CHANGED: \(recognizer.translationInView(view))") 

     let translation = recognizer.translationInView(view) 

     currentView.view.center.x += translation.x 
     pendingView.view.center.x += translation.x 

     recognizer.setTranslation(CGPointZero, inView: view) 
    } 

    if recognizer.state == .Ended { 
     if recognizer.view!.center.x > view.bounds.size.width { 
      // Animate the view to position 
     } else { 
      // Animate the view back to original 
     } 
    } 
} 

В то время как это работает, я все еще имею вопрос с началом панорамирования. Когда пользователь быстро проведет поиск, translation будет иметь значение, достаточно большое, чтобы начать панорамирование, глядя «негладкой».

Например, быстрым ходом translation начнется со значения 100. Затем значение добавляется к center.x видов, вызывающих нежелательный эффект.

Я заметил, что у Safari есть жест экрана, а также для изменения видов, и этот эффект не возникает независимо от того, насколько быстро происходит салфетка. Это также не происходит с обычным UIPanGestureRecognizer.

Я пробовал обернуть «анимацию» в UIView.animateWithDuration(). Это выглядит более гладко, но тогда он чувствует, что это просто отстает от реального жеста, в отличие от того, как это делается в Safari.

Может кто-нибудь, пожалуйста, скажите мне лучший способ панорамирования просмотров, чтобы он выглядел так же гладко, как в Safari?

EDIT:
Я добавил несколько строк, чтобы проверить значение перевода и проблема прыгает от 0 до некоторого значения, вызывающего нежелательное поведение. Неважно, где я положил recognizer.setTranslation(CGPointZero, inView: view).

Выход:

INITIAL: (21.5, 0.0) 
BEGAN: (21.5, 0.0) 
INITIAL: (188.0, -3.0) 
CHANGED: (188.0, -3.0) 

После некоторого более тестирования:

func changeView(recognizer: UIScreenEdgePanGestureRecognizer) { 
    println("INITIAL: \(recognizer.translationInView(view))") 
    recognizer.setTranslation(CGPointZero, inView: view) 
} 

INITIAL: (0.0, 0.0) 
INITIAL: (130.5, -35.5) 

FINAL:
Похоже, создание и подготовка нового взгляда вызывает какое-то незначительное отставание в Began , Малой величины задержки достаточно, чтобы создать разницу в переводе 100-200.

Наверное, нужно предварительно загрузить представления где-нибудь еще, я думаю.

+0

Ну, может быть, что-то еще происходит, потому что мои тесты не согласуются с вашими (я добавил некоторые результаты регистрации в свой ответ). Является ли ваш распознаватель жестов в конфликте с чем-то другим, так что он занимает много времени, чтобы принять решение признать? – matt

+0

Я собирался обновить свой вопрос. Кажется, что создание представления вызывает некоторое отставание в «Бытии». Думаю, мне придется предварительно загружать представления где-то еще? (Создание нового представления включает использование 'filter' 4 или 5 раз, передача некоторых значений и обычная настройка child/parent). –

+0

Нужно просто использовать методы делегатов для определения приоритетов конфликтующих распознавателей жестов. - Я добавлю это к своему ответу. – matt

ответ

1

Это не решит все ваши проблемы, так как, как вы правильно сказали, распознаватель жестов жесткого диска на экране немного коррумпирован в своем поведении; но обратите внимание, что вы опускаете один ценный фрагмент данных - вопрос о том, что recognizer.translationInView является в .Began состоянии. В то время, очевидно, у пальца уже значительно сдвинулся; потому что, если бы этого не произошло, мы бы не узнали это как жест жесткости экрана. Таким образом, вы будете гораздо счастливее, я думаю, если вы строите свои тесты, как это:

switch recognizer.state { 
    case .Began: 
     // ... do initial setup 
     fallthrough // <-- TAKE NOTE 
    case .Changed: 
     // respond to changes 
    default:break 
    } 

Таким образом, вы будете захватить недостающий геодезическую и ответить на него, и скачок не будет совсем так плохо.

Я попытался войти в обоих began и changed и моих номеров (показать translationInView с не не setTranslation до нуля) являются такие вещи:

began 
changed 
(-16.5, 0.0) 
changed 
(-41.5, 0.0) 
changed 
(-41.5, 0.0) 
changed 
(-58.5, 0.0) 

(Первый, которому предшествует began, является fallthrough исполнение changed.) Итак, да, мы переходим от ничего к -41 очень быстро, но, по крайней мере, есть промежуточное значение -16.5, поэтому оно не так круто.

Также я должен добавить, что если есть серьезная задержка и прыжок, вполне возможно, что у вас есть несколько конфликтующих распознавателей жестов. Если это так, вы можете обнаружить этот факт, используя методы делегата, такие как gestureRecognizer:shouldRequireFailureOfGestureRecognizer: - что также позволит вам установить приоритеты между ними и, возможно, сделать другой g.r. уступить дорогу раньше.

+0

Очень интересно. Не думал об использовании здесь провалов, я пробовал так много разных вариантов. Будет тест после ужина :) –

+0

Я тестировал его, как вы предлагали, но, к сожалению, он остается тем же. Я добавил редактирование в своем сообщении с указанием причины этого (я думаю). Редактирование сделано с вашим предложением, просто не изменило весь вопрос. –

Смежные вопросы