Как отменить прокрутку в UIScrollView

Я использую UIScrollView для создания пользовательского интерфейса большого размера (больше 320 пикселей) на iPhone.

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

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

@Chris Hanson: Почему вы удалили iPhone и UIScrollView из тегов? Это правильные теги - какао-тач может быть добавлен, но не должен здесь стоять отдельно.

Emil 23.06.2010 13:34

Я не удалял и не редактировал эти теги :(

fish potato 24.06.2010 08:51

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

Chris Hanson 01.07.2010 08:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
16
3
25 726
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

UIScrollView имеет свойство scrollEnabled, которое позволяет программно отключить прокрутку. У него также есть делегат (UIScrollViewDelegate), который позволяет вам видеть такие события, как начало / конец прокрутки. Похоже, вы сумеете приготовить что-нибудь, комбинируя эти варианты каким-либо образом.

Спасибо за ваш ответ. Я сейчас попробую ваше решение.

fish potato 20.12.2008 17:13

Хороший ответ, расплывчатый, но достаточно, чтобы начать. +1

Dan Rosenstark 28.09.2010 09:33

Вы также можете создать подкласс UIScrollViewController и переопределить методы touchesBegan, touchesMoved и touchesEnded. Если ваша реализация никогда не вызывает реализацию суперкласса, она не будет прокручиваться.

Спасибо за ваш ответ. Я попробовал ваше предложение, и оно сработало !!

fish potato 06.01.2009 17:25
Ответ принят как подходящий

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

Кроме этого, вы не можете идентифицировать прикосновения в подпредставлениях, поскольку UIScrollView имеет тенденцию обрабатывать все прикосновения самостоятельно и не передает их своим подпредставлениям.

Всего наилучшего.

Спасибо за ваш ответ. Я пытался переопределить методы touchShouldBegin / touchesShouldCancel ..., но эти методы никогда не вызывались. Возможно, что-то не так с моим кодированием, но я могу остановить прокрутку, переопределив методы touchBegin / touchesMoved / touchedEnded. Спасибо!

fish potato 06.01.2009 17:27

Вы делаете это в подклассе UIScrollView? Только после этого будут вызваны методы. Поэтому вместо вашего UIViewController, использующего UIView в качестве представления, он должен использовать подкласс UIScrollView в качестве представления

lostInTransit 07.01.2009 14:36

Да, я пробовал это в подклассе UIScrollView. У меня возникла проблема в моей реализации (только переопределение touchesBegan ...), поэтому я продолжаю пытаться найти причину, по которой метод touchesShouldBegin никогда не вызывается.

fish potato 10.01.2009 05:37

У меня такая же проблема. Для меня это произошло из-за того, что базовое subview (UIImageView) не имеет для userInteractionEnabled значения YES.

Ken Joyner 09.03.2011 03:23

Это неправильный ответ, не должен быть принятым ответом. Вам вообще НЕ нужно создавать подклассы UIScrollView. В UIScrollView есть ошибка, которая нарушает работу UIView - если вы исправите свой UIView, все прикосновения работают отлично (они переходят в UIViewController), И прокрутка продолжает работать, как ожидалось. Секрет в том, чтобы правильно установить nextResponder в подклассе UIView, когда Apple случайно удаляет его.

Adam 31.08.2012 19:17

Самый простой способ сделать это - установить delayContentTouches на NO для прокрутки. Таким образом, поведение по умолчанию устанавливается так, что все, что является UIControl, сразу передает штрихи элементу управления, а все остальное будет прокручиваться.

Если для этого параметра установлено значение NO, поведение противоположно тому, что хочет OP. Если установлено ДА, это ненамного лучше :)

Dan Rosenstark 28.09.2010 09:40

Свойство, которое вас действительно интересует - и я на самом деле сейчас это тестирую, потому что у меня такая же проблема, как и у вас, - это canCancelContentTouches.

If the value of this property is NO, the scroll view does not scroll regardless of finger movement once the content view starts tracking.

Если это не дает желаемых результатов, создайте подкласс UIScrollView и переопределите метод touchesShouldBegin:withEvent:inContentView, что и предлагает принятый ответ.

Моя проблема заключалась в том, что пользователь мог рисовать, но просмотр прокрутки захватил прикосновение и прокрутку вместо рисования. Это мое рабочее решение:

В моем виде чертежа у меня есть:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    // Disable scroll on touch begin
    setContainerScrollingEnabled(false)
    super.touchesBegan(touches, with: event)
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    // Reenable scroll on touch end
    setContainerScrollingEnabled(true)
    super.touchesEnded(touches, with: event)
}

private func setContainerScrollingEnabled(_ enabled: Bool) {

    // loop up superviews to find the scrollview
    func scrollingSuperview(of view: UIView) -> UIScrollView? {
        guard let superview = view.superview else { return nil }
        if let scrolling = view.superview as? UIScrollView { return scrolling }
        return scrollingSuperview(of: superview)
    }

    // and switch on/off scrolling
    let scrollView = scrollingSuperview(of: self)
    scrollView?.isScrollEnabled = enabled
}

и в контроллере представления, содержащем представление прокрутки, у меня есть:

// Not sure what exactly this does, but I think it allows the drawing view to have precedence. This was the missing piece of the puzzle.
scrollView.delaysContentTouches = false

Это сработало для меня. Кстати, вы также можете включить прокрутку на touchCancelled!

Jared Updike 10.10.2019 02:56

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