views:

249

answers:

1

Hi,

This is a general question to a specific problem.

I am using a UIScrollView in an app that displays photographs. on iOS < 4.0, zooming works great. the same app running on iOS 4.0.x has problems zooming. specifically, if the image does not fill the view (and black bands appear at top/bottom), the first zoom is jerky and garbage data is shown on the bottom of the screen.

the source code to analyze is way to complex and spread out to adequately share here. Can anyone suggest any areas to look at that might cause this strange behavior?

thanks! Mark

edit: here's the code from the double tap handler (borrowed from the tapDetectingImageView sample code):

- (void)tapDetectingImageView:(TapDetectingImageView *)view gotDoubleTapAtPoint:(CGPoint)tapPoint {
    // double tap zooms in
    float newScale = [self zoomScale] * ZOOM_STEP;
    CGRect zoomRect = [self zoomRectForScale:newScale withCenter:tapPoint];
    [self zoomToRect:zoomRect animated:YES];
}

I can force the weirdness if I change the animated parameter in the call to zoomToRect. when animated is NO, my image becomes 2 images superimposed one on top of the other. the bottom image is the original zoom level, the top image is the new zoom level. if I swipe the screen to pan, the image is refreshed. It's almost as if a call to layoutSubviews or DrawRect is not getting called.

A: 

This may or may not be related, but the way that UIScrollView dealt with scale factors changed in an undocumented way in iPhone OS 3.2+.

Previously, if you used -scrollViewDidEndZooming:withView:atScale: to re-render your content by applying the identity transform to the view and then redrawing your image sharply at the new scale factor, UIScrollView would ignore this and keep handing you absolute scale factors based on the initial size of the view.

On iPhone OS 3.2+, UIScrollView now gives you a relative scale factor based on the last time you reset the transform of the content view to be the identity transform. This can lead to significant scaling differences between the various OS versions.

Brad Larson
I edited my question with some code and some debugging results I got last night after I posted my question. Sounds like the scale factor might be an issue. Can you point to something that describes this change in 3.2+, possible with some demo or tutorial code? thanks!
iPixFolio
@iPixFolio - What are you returning from `-viewForZoomingInScrollView:`? From the above code and description, it almost sounds like a different view is being returned at different times. In any case, I talk a bit more about the change in zoom behavior in this answer: http://stackoverflow.com/questions/448285/how-do-i-reset-after-a-uiscrollview-zoom/451629#451629 . As far as code goes, you just need to detect the current OS if targeting something earlier than 3.2 in order to provide two different scale-handling paths.
Brad Larson
@Brad, I am returning different views at different times. This code uses the trick of 1 scrollview for scrolling multiple images and zooming, instead of nesting multiple scrollviews within another. In which methods do I need to make changes for the scale factor?
iPixFolio
@iPixFolio - I've only ever dealt with scroll views that had a single content view. Switching the view that is zoomed sounds like the most likely cause of your odd behavior. Because zoom scale is now relative, it may be using the previous transform returned from a zooming action (which may have occurred on a different view) as a basis for the zoom that will be performed on the current view. If so, you may need to account for the transforms it's trying to apply in a complex way. I don't have a good suggestion for how to handle that simply.
Brad Larson
this turned out to be bug elsewhere that I introduced when I changed my async load logic. I use thumbnails until the real image is downloaded (in background), and then I remove the thumbnail imageview . the bug was that I did not always remove the thumbnail imageview. the other bug had to do with zoomToRect. this does not force a redraw. the two bugs combined gave me the weirdness. once I corrected those 2 bugs, now it works even better than before.thanks for your help!
iPixFolio