我使用UIScrollView在iPhone上制作大尺寸(大于320px)的UI。
我创建了一个UIScrollView实例,并在其上添加了一些子视图。 问题是,我希望只有当用户触摸子视图外部时才启用滚动, 并在用户触摸其中一个子视图时停止滚动。
我阅读了文档并尝试查找示例,但没有找到好的线索。 如果您有任何想法,请帮助我。
我使用UIScrollView在iPhone上制作大尺寸(大于320px)的UI。
我创建了一个UIScrollView实例,并在其上添加了一些子视图。 问题是,我希望只有当用户触摸子视图外部时才启用滚动, 并在用户触摸其中一个子视图时停止滚动。
我阅读了文档并尝试查找示例,但没有找到好的线索。 如果您有任何想法,请帮助我。
UIScrollView有一个scrollEnabled属性,允许你通过编程来禁用滚动。它还有一个代理(UIScrollViewDelegate),允许你查看诸如滚动开始/结束等事件。似乎你可以通过这些选项以某种方式组合起来实现一些功能。
你真正感兴趣的属性是canCancelContentTouches
,我现在正在测试这个问题,因为我和你一样也有同样的问题。
如果这个属性的值为NO,无论手指如何移动,一旦内容视图开始跟踪,滚动视图都不会滚动。
如果这不能满足你的需求,可以子类化UIScrollView并重写touchesShouldBegin:withEvent:inContentView
方法,这是被接受答案所建议的。
delaysContentTouches
设置为NO
,这样滚动视图的默认行为就是,任何被识别为UIControl的东西会立即将触摸事件传递给控件,而其他一切则会进行滚动。如果您想检测UIScrollView中任何子视图中的触摸事件,您需要继承UIScrollView并重写touchesShouldBegin
和touchesShouldCancelInContentView
方法,这些方法是专为此目的创建的。
除此之外,没有其他方法可以识别UIScrollView中子视图中的触摸。因为UIScrollView倾向于自己处理所有的触摸事件,并不会将它们传递给其子视图。
祝一切顺利。
我的问题是有一个用户可以在其中绘制的视图,但滚动视图却会劫持触摸并滚动而不是绘制。这是我的解决方案:
在我的绘图视图中,我有:
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