Я использую UIScrollView для создания пользовательского интерфейса большого размера (больше 320 пикселей) на iPhone.
Я создал экземпляр UIScrollView и добавил в него несколько подпредставлений. Проблема в том, что я хочу включить прокрутку только тогда, когда пользователь касается вне подпредставлений, прекратить прокрутку, когда пользователь касается одного из подпредставлений.
Я читал документы и пытался найти образцы, но не могу найти хорошей подсказки. Если у вас есть идеи, пожалуйста, помогите мне.
Я не удалял и не редактировал эти теги :(
Потому что, когда я делал это редактирование, загрязнение пространства тегов именами классов и избыточной информацией было не очень хорошей идеей. Это все еще не так, я просто отказался от исправления этого дерьма.





UIScrollView имеет свойство scrollEnabled, которое позволяет программно отключить прокрутку. У него также есть делегат (UIScrollViewDelegate), который позволяет вам видеть такие события, как начало / конец прокрутки. Похоже, вы сумеете приготовить что-нибудь, комбинируя эти варианты каким-либо образом.
Спасибо за ваш ответ. Я сейчас попробую ваше решение.
Хороший ответ, расплывчатый, но достаточно, чтобы начать. +1
Вы также можете создать подкласс UIScrollViewController и переопределить методы touchesBegan, touchesMoved и touchesEnded. Если ваша реализация никогда не вызывает реализацию суперкласса, она не будет прокручиваться.
Спасибо за ваш ответ. Я попробовал ваше предложение, и оно сработало !!
Если вы хотите обнаруживать касания внутри любого из подпредставлений UIScrollView, вам придется создать подкласс UIScrollView и переопределить методы touchesShouldBegin и touchesShouldCancelInContentView, специально созданные для этой цели.
Кроме этого, вы не можете идентифицировать прикосновения в подпредставлениях, поскольку UIScrollView имеет тенденцию обрабатывать все прикосновения самостоятельно и не передает их своим подпредставлениям.
Всего наилучшего.
Спасибо за ваш ответ. Я пытался переопределить методы touchShouldBegin / touchesShouldCancel ..., но эти методы никогда не вызывались. Возможно, что-то не так с моим кодированием, но я могу остановить прокрутку, переопределив методы touchBegin / touchesMoved / touchedEnded. Спасибо!
Вы делаете это в подклассе UIScrollView? Только после этого будут вызваны методы. Поэтому вместо вашего UIViewController, использующего UIView в качестве представления, он должен использовать подкласс UIScrollView в качестве представления
Да, я пробовал это в подклассе UIScrollView. У меня возникла проблема в моей реализации (только переопределение touchesBegan ...), поэтому я продолжаю пытаться найти причину, по которой метод touchesShouldBegin никогда не вызывается.
У меня такая же проблема. Для меня это произошло из-за того, что базовое subview (UIImageView) не имеет для userInteractionEnabled значения YES.
Это неправильный ответ, не должен быть принятым ответом. Вам вообще НЕ нужно создавать подклассы UIScrollView. В UIScrollView есть ошибка, которая нарушает работу UIView - если вы исправите свой UIView, все прикосновения работают отлично (они переходят в UIViewController), И прокрутка продолжает работать, как ожидалось. Секрет в том, чтобы правильно установить nextResponder в подклассе UIView, когда Apple случайно удаляет его.
Самый простой способ сделать это - установить delayContentTouches на NO для прокрутки. Таким образом, поведение по умолчанию устанавливается так, что все, что является UIControl, сразу передает штрихи элементу управления, а все остальное будет прокручиваться.
Если для этого параметра установлено значение NO, поведение противоположно тому, что хочет OP. Если установлено ДА, это ненамного лучше :)
Свойство, которое вас действительно интересует - и я на самом деле сейчас это тестирую, потому что у меня такая же проблема, как и у вас, - это 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!
@Chris Hanson: Почему вы удалили iPhone и UIScrollView из тегов? Это правильные теги - какао-тач может быть добавлен, но не должен здесь стоять отдельно.