UIScrollView的一些特点

是个麻烦的控件,这里先问几个问题:

1.  如果我触摸一下屏幕,哪个view会最先收到触摸消息呢(touchesBegan)?

答案是,如果所有view都是UIView的话,那么最外层的子view会先收到该消息。这个机制就是通过 UIView中的hitTest:withEvent:  实现的。这个函数的逻辑是这样的(官方文档):

This method traverses the view hierarchy by sending the pointInside:withEvent: message to each subview to determine which subview should receive a touch event. If pointInside:withEvent: returns YES, then the subview’s hierarchy is traversed; otherwise, its branch of the view hierarchy is ignored. You rarely need to call this method yourself, but you might override it to hide touch events from subviews.

也就是说底层的父view的hitTest函数先被调用,在这里遍历调用subView的hitTest,直到找到最外层的subView,然后返回该view,系统再把touch事件传给这个view。

 

2. tableView的cell我点击一下,打开一个新页面,但如果飞快的swipe一下,tableView会是上下滚动,而cell即不会highlight,也不会打开新页面,这是如何实现的呢?

tableView继承自UIScrollView,这个功能实际上是UIScrollView来实现的。它是如何做的呢?根据问题一,UIView的默认行为是将touch事件传递给最外层的subView。实际上UIScrollView重载了hitTest:withEvent:,他永远只返回自己。

 

这里把UIScrollView的几个要点总结下:

从你的手指touch屏幕开始,scrollView开始一个timer,如果:

1.  150ms内如果你的手指没有任何动作,消息就会传给subView。

2.  150ms内手指有明显的滑动(一个swipe动作),scrollView就会滚动,消息不会传给subView,这里就是产生问题二的原因。

3. 150ms内手指没有滑动,scrollView将消息传给subView,但是之后手指开始滑动,scrollView传送touchesCancelled消息给subView,然后开始滚动。

观察下tableView的情况,你先按住一个cell,cell开始高亮,手不要放开,开始滑动,tableView开始滚动,高亮取消。

 

delaysContentTouches的作用:

这个标志默认是YES,使用上面的150ms的timer,如果设置为NO,touch事件立即传递给subView,不会有150ms的等待。

 

cancelsTouches的作用:

这个标准默认为YES,如果设置为NO,这消息一旦传递给subView,这scroll事件不会再发生。

posted on 2012-01-07 21:49  日虾夜饺  阅读(3082)  评论(0编辑  收藏  举报

导航