События касания UIScrollView во время анимации не срабатывают с помощью animateWithDuration:но отлично работает с UIView BeginAnimations:
-
26-09-2019 - |
Вопрос
У меня есть подкласс UIScrollView, который я программно прокручиваю с помощью анимации UIView.
Я бы хотел, чтобы пользователь мог коснуться или увеличить содержимое UIImageView в представлении прокрутки. пока анимация происходит.
Это отлично сработало при использовании формулировки, похожей на эту:
- (void) scrollSmoothlyatPixelsPerSecond:(float)thePixelsPerSecond {
// distance in pixels / speed in pixels per second
float animationDuration = _scrollView.contentSize.width / thePixelsPerSecond;
[UIView beginAnimations:@"scrollAnimation" context:nil];
[UIView setAnimationCurve: UIViewAnimationCurveLinear];
[UIView setAnimationDuration:animationDuration];
_scrollView.contentOffset = CGPointMake(_scrollView.contentSize.width, 0);
[UIView commitAnimations];
}
Теперь, начиная с iOS 4.0, UIView BeginAnimations:обескуражен.Поэтому я попытался обновить свой код, используя блок и UIView animateWithDuration:Прокрутка работает идентично описанному выше.
Ключевое и сводящее с ума отличие заключается в том, что во время анимации UIScrollView и другие представления больше не реагируют на методы обработки событий:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
Также не:
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;
вам позвонят при попытке масштабирования.
Отредактируйте для ясности:Никакой UIView не реагирует на события касания.Это не ограничивается только UIScrollView.Одноранговый элемент UIScrollView, UIToolbar, не реагирует на события касания, как и другие кнопки, которые являются подпредставлениями однорангового элемента UIScrollView.Похоже, что весь родительский UIView заблокирован от взаимодействия с пользователем. пока идет анимация.Опять же, после завершения анимации все вышеперечисленные UIView снова становятся отзывчивыми.
Все они вызываются в UIView BeginAnimations:формулировка независимо от состояния анимации.
Мой animateWithDuration:код немного другой - но различия не существенны.Как только анимация завершается, вышеуказанные события касания снова вызываются...
вот мой код анимации:
- (void) scrollSmoothlyToSyncPoint:(SyncPoint *) theSyncPoint andContinue:(BOOL)theContinueFlag{
float animationDuration = theSyncPoint.time - [player currentTime];
[UIView animateWithDuration:animationDuration
delay:0
options:UIViewAnimationOptionCurveLinear
animations:^{
[_scrollView setContentOffset:theSyncPoint.contentOffset];
}
completion:^(BOOL finished){
if (theContinueFlag) {
SyncPoint *aSyncPoint = [self nextSyncPoint];
if (aSyncPoint) {
[self scrollSmoothlyToSyncPoint:aSyncPoint andContinue:YES];
}
}
}];
}
Единственный обработчик событий, который срабатывает во время приведенного выше блока анимации:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
Итак, вопрос:Должен ли я - игнорировать Apple обескураженный label и продолжать использовать формулировку BeginAnimation?Должен ли я переопределить масштабирование и другие сенсорные события с помощью hitTest?Есть ли какие-либо знания о разнице в реализации между блоками анимации, которые могут помочь мне решить эту проблему?Есть ли что-то очевидное, чего мне не хватает?
Я новичок в Apple, поэтому не знаю, насколько серьезно относиться к их обескураженный ярлык.Но если этот API устареет и исчезнет, я бы предпочел двигаться в долгосрочном направлении.
большое спасибо за ваше внимание.
Решение
Вам просто нужно включить опцию UIViewAnimationOptionAllowUserInteraction при вызове анимации следующим образом:
[UIView animateWithDuration:animationDuration
delay:0
options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
<snip>];
Это подлый человек, я знаю!;)
Ре:Тег «Обескураженный». В общем, когда Apple советует вам не делать что-то в отношении разработки приложений, работающих на их платформах, обычно это делается для вашего же блага.Итак, вы правы, желая использовать блоки анимации вместо неуклюжего старого способа.
Другие советы
quickthyme
ответ правильный.Вот фрагмент в Swift
Свифт 4
UIView.animate(
withDuration: 0.3, // specify animation duration here
delay: 0, // specify delay if needed
options: [
UIView.AnimationOptions.allowUserInteraction,
UIView.AnimationOptions.curveLinear
],
animations: {
// animations code
}
)