UIScrollView предотвращает прокрутку в одном направлении независимо от contentSize/Offset

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

Например, кто-то может проходить тест с десятью вопросами (по одному вопросу на страницу), но прокрутка не будет работать, если человек не ответил на вопрос на текущей странице.

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

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

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

Я пытался использовать настраиваемое представление для страниц, на которых заблокировано пролистывание в определенном направлении, но оно не работает, поскольку я не смог найти способ предотвратить обнаружение прокрутки в режиме прокрутки, не затрагивая страницы, на которых пролистывание должно работать в обычном режиме. . Я увидел, что могу установить для свойства ExclusiveTouch пользовательского представления значение YES, и предположил, что, поскольку он будет получать все события, я смогу обрабатывать пролистывания с помощью пользовательских распознавателей жестов и пересылать события, если пролистывание разрешено, или игнорировать их, если нет. Это не сработало, ScrollView всегда ловит события свайпа.

Я чувствую, что исчерпал все возможности и не могу найти никого, у кого были бы такие же потребности.

Вот мне интересно, это вообще возможно? Если да, потребуются ли плохие хаки или создание нового пользовательского вида прокрутки?

Любая помощь/идея будет принята с благодарностью.


person Deratrius    schedule 28.09.2011    source источник


Ответы (2)


используйте свое условие в соответствующем месте вашего кода, где вы хотите заблокировать прокрутку/пейджинг, и установите для pagingEnabled или scrollEnabled вашего объекта scrollView значение NO.

РЕДАКТИРОВАТЬ:

Нужно было более внимательно прочитать ваше требование. Для ваших нужд лучшим решением будет использование нескольких представлений, скользящих по сторонам в зависимости от ваших условий. Анимируйте их. Распознаватели жестов также должны помочь. И я не говорю здесь о scrollView. View1 -> условие -> проходит? (действие кнопки или жест) -> анимация в view2 и так далее.

Если вам действительно необходимо использовать scrollView, лучшее, что вы можете сделать, это установить для contentSize ширину экрана и установить для alwaysBounceHorizontal значение NO, чтобы предотвратить эффект автоматического подпрыгивания:

CGRect size = scrollView.contentSize;
size.width = CGRectGetWidth(scrollView.frame);
scrollView.contentSize = size;
scrollView.alwaysBounceHorizontal = NO;
person Bourne    schedule 28.09.2011
comment
Это не сработает, как я уже сказал, мне нужно иметь возможность прокручивать влево, но не вправо (или вправо, но не влево). Это решение будет блокировать свайпы в обоих направлениях. - person Deratrius; 29.09.2011
comment
Да, я думаю, что настройка contentSize вручную и отскок на NO с представлением сверху, которое улавливает пролистывания через распознаватели UIGesture и фильтрует их, — единственный выход. Увы, кажется, что вид прокрутки всегда улавливает свайпы, если только userInteraction не отключен. Это означает, что мне нужно будет использовать этот настраиваемый фильтр обнаружения везде (даже когда это не нужно). Возможно, мне придется это сделать, но я надеялся, что, возможно, есть более простое решение. Спасибо за помощь! - person Deratrius; 03.10.2011

Найденный в другом посте, вот как я решил ту же проблему, что и у меня.

Поместите это в контроллер просмотра и установите его как делегата UIScrollView.

CGPoint oldOffset;  // instance variable

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    oldOffset = scrollView.contentOffset;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (scrollView.contentOffset.x < oldOffset.x) 
    {
        [scrollView setContentOffset:oldOffset];
    }
}
person Murat Ögat    schedule 07.05.2013
comment
Я был вне этого проекта около полутора лет, поэтому я не могу проверить это решение. Тем не менее, спасибо за публикацию! Возможно, это поможет другим людям с такой же проблемой. - person Deratrius; 07.05.2013
comment
Да, я заметил, что это старый, но я все равно хотел опубликовать. После его реализации я получил почти желаемое поведение. Единственная проблема, которую я заметил после тестирования, заключается в том, что иногда вид прокрутки может прокручиваться на 5-10 пикселей вправо, хотя у меня включен пейджинг. (Возможно, из-за странного жеста) Так что на самом деле это не идеальное решение, но с этой небольшой прокруткой можно справиться, проверив видимый прямоугольник и прокрутив его назад, если это необходимо. Будем надеяться, что это поможет кому-то. - person Murat Ögat; 08.05.2013