1

Note: This is not a performance problem! I am aware of the benefits of cell dequeuing in UITableView.

For testing I created a UIScrollView with some simple opaque UIView subviews which have a black background color on a white scroll view, and 100 points spacing between them so there is something to scroll. Very light-weight. Nothing else. Really trust me, it is not heavy.

I notice a huge difference between beginning to scroll a scroll view and beginning to scroll a table view.

When I touch down on the scroll view and immediately begin to drag, it lags behind by about 0.25 seconds and then suddenly catches up. From there it is fluid, no lags anymore until I touch up and touch down again.

On a much, much bigger and more complex UITableView when I do the same thing there is no initial delay of 0.25 seconds before it begins scrolling.

I tried to alter every property possible but just cannot eliminate this stupid delay. I believe it has to do with the scroll view wanting to figure out if a touch is meant to happen on a subview, and then sees if user moves it's finger too much. Then it begins scrolling.

Now the crazy thing is UITableView is a UIScrollView itself and I want to make my UIScrollView start scrolling as fast as a UITableView. How?

Edit: Sh.. I found something CRAZY!

NSLog(@"GR = %@", self.gestureRecognizers);


GR = (

"<UIScrollViewDelayedTouchesBeganGestureRecognizer: 0x13e930; 
state = Possible; 
delaysTouchesBegan = YES; 
view = <TestScrollView 0x13e380>; 
target= <(action=delayed:, target=<TestScrollView 0x13e380>)>>",

"<UIScrollViewPanGestureRecognizer: 0x13ee00; 
state = Possible; 
delaysTouchesEnded = NO; 
view = <TestScrollView 0x13e380>; 
target= <(action=handlePan:, target=<TestScrollView 0x13e380>)>>"

)

This is iOS 4, and there is no panGestureRecognizer property in iOS4. The most suspicious is UIScrollViewDelayedTouchesBeganGestureRecognizer with delaysTouchesBegan. Damn! How can I set that to NO in iOS4?

Proud Member
  • 40,078
  • 47
  • 146
  • 231

2 Answers2

1

EDIT:

I have found this answer in S.O.

Basically, you could try subclassing UIScrollView and overriding touchesShouldCancelInContentView so that it returns always NO:

- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
      return NO;
}

PREV ANSWER:

I tried to alter every property possible but just cannot eliminate this stupid delay. I believe it has to do with the scroll view wanting to figure out if a touch is meant to happen on a subview, and then sees if user moves it's finger too much. Then it begins scrolling.

I think this is the right hypothesis. Indeed, the responder chain and event management is designed to work in a way that the most-specific view is the one to receive the notification of the event; during this process, each view in the responder chain is asked until the deepest one is found.

Touch events. The window object uses hit-testing and the responder chain to find the view to receive the touch event. In hit-testing, a window calls hitTest:withEvent: on the top-most view of the view hierarchy; this method proceeds by recursively calling pointInside:withEvent: on each view in the view hierarchy that returns YES, proceeding down the hierarchy until it finds the subview within whose bounds the touch took place. That view becomes the hit-test view.

(source)

Possibly UITableView does something to alter this behavior.

Making your scroll view the first responder:

 [scrollView becomeFirstResponder]

will not work, since this affects only the dispatch of non-touch events.

You could try though making the inner view not touch enabled and see if that makes a difference.

Community
  • 1
  • 1
sergio
  • 68,819
  • 11
  • 102
  • 123
0

Have you tried subViews.userInteractionEnabled = NO;? This would help you eliminate the touches hypothesis.

Benedict Cohen
  • 11,912
  • 7
  • 55
  • 67