I think there are two parts to this problem. The first is the determination of the user's intention, and the second is the proper management to respond to this intention.
Definition of Intent
I think itβs important to clearly understand what the user intends. Imagine this scenario: the user starts touching the screen and moves his finger to the left, but also a little up. Perhaps the user intended to scroll through the view and did not intend to change the date at all. It would be bad if you scroll the view and change the date, especially as it moves off the screen. Therefore, to determine what the user intends, I propose the following algorithm:
When the user starts touching the screen, record the starting position. When the user finger begins to move away from this position, the controls should not respond at all. As soon as the touch moves past a certain threshold distance from the starting position, determine if it has been moved more horizontally or vertically. If it moves vertically, the user intends to change the date, so ignore the horizontal part of the movement and change only the date. If it moves more horizontally, the user intends to scroll the view, so ignore the vertical part of the movement and view only the scroll.
Implementation
To implement this, you need to handle events before a UIScrollView or date picker does. There are probably several ways to do this, but it comes to mind in particular: create a custom UIView called ScrollingDateMediatorView. Set UIScrollView as a child of this view. Override the ScrolllingDateMediatorView method hitTest: withEvent: and pointInside: withEvent :. These methods should perform the same tests that usually occur, but if the result is a date picker, get yourself back. It effectively captures any touch events designed to select a date, allowing ScrollingDateMediatorView to handle them first. You then implement the algorithm described above in various touch * methods. In particular:
In the touchhesBegan: withEvent method, save the starting position.
In contacts: Love: withEvent, if the user's intention is not yet known, determine whether the touch has gone far enough from the starting position. If so, determine if the user intends to scroll or change the date and save that intention. If the user's intention is already known and it has changed the date, send the date selection by clicking the message Message: withEvent, otherwise send the message UhescrollView message touchhesMoved: withEvent. You will need to do some similar work within touchesEnded: withEvent and touchesCancelled: withEvent to ensure that other views receive the appropriate messages. Both of these methods should reset the stored values.
After the events are correctly propagated, you may have to try some user tests to set the threshold for movement.