English 中文(简体)
How to filter touch events for a UIScrollView?
原标题:

I have a view that displays a PDF. It should be zoomable, so I also created a UIScrollView, and in its delegate I implemented viewForZoomingInScrollView to return the PDF view. So far so good. However, when the user reaches the edge of a zoomed PDF page, I d like to flip to the next page. Sounds easy, yet I can t seem to figure out how to do it.

I ve tried some different approaches:

  1. Using scrollViewDidScroll to detect if scrolling has reached the edge. The problem here is that if zoomScale is 1, and therefore scrolling is not possible, then this function is never called. But the UIScrollView still swallows all touch events, so I also can t detect reaching the edge in touchesMoved. Setting canCancelContentTouches to NO when not zoomed is not an option, as that would also prevent zooming in.

  2. Subclassing UIScrollView, and forwarding some of the touch events to the next responder. Unfortunately when UIScrollView detects a drag operation and cancels the touch, touchesMoved and touchesEnded are not called even for the UIScrollView subclass anymore. Again, setting canCancelContentTouches to NO is not good, as that would also prevent some desired UIScrollView functionality.

  3. Creating a transparent view on top of the scroll view (as a sibling of it), so that this view gets all touch events first, and then forwarding some of the touches to the scroll view. Unfortunately the scroll view doesn t respond to these calls.

  4. I can t use touchesShouldCancelInContentView, becasue that doesn t get the actual touches as an argument, and whether or not I want the scroll view to handle the touch event also depends on the properties of the touch event itself (eg. a touch movement in a direction in which we re already at the edge should not be cancelled by the scroll view, but a movement in the other direction could be).

Looks like whatever UIScrollView is doing is not initiated from touchesBegan / touchesMoved, but instead it gets some notifications about the touches way before that. Possibly in some undocumented way that I can t intercept, nor reproduce.

So is there any way to get notified about all touch movements done over a UIScrollView, while still being able to use (when certain conditions apply) the UIScrollView for zooming and scrolling?

问题回答

Ok, so here s what I did in the end:

  • Leaving all scrolling and zooming up to UIScrollView, and handling page turning in the UIScrollViewDelegate s scrollViewDidEndDragging:willDecelerate: is almost a solution, except that this function is never called if the whole content is on-screen, so dragging / scrolling is not possible.
  • Swipes in this case are handled in a ViewController s touchesBegan / touchesEnded functions, but for this to work, we need to make sure that the UIScrollView does not cancel these events. However, in other cases the UIScrollView should be able to cancel touches so that it can do zooming and scrolling.
  • The UIScrollView should be able to cancel touches if:
    • Scrolling is possible (and needed) because the whole content doesn t fit on screen (zoomScale > 1 in my case), OR
    • The user touched the screen with two fingers, so that zooming in and out works.
  • When scrolling is not possible, and the user single-touched the screen, then touches should not be cancelled, and touch events should be forwarded to the view controller.

  • So I created a UIScrollView subclass.

  • This subclass has a property pointing to the ViewController.
  • Using the touchesXXX methods I keep track of the current touch count.
  • I forward all touch events to the ViewController.
  • And finally, I ve overridden touchesShouldCancelInContentView:, and return NO when zoomScale <= 1 and touchCount == 1.




相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签