Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView programmatically set contentOffset problem

I am creating an ImageViewer similar to the Photos app. I have a PagingScrollView that is the view of a view controller (created in loadView). The pages are UIScrollViews with UIImageView subviews. Everything works hunky dory until I try to 'skip' (set content offset) to an index besides the first one. If I skip to say, image 'i', the image is correctly displayed but if the user performs a single tap gesture the contentOffset resets itself back to display image '0'. The error does not happen with other gestures such as drag and it does not happen with touch if you do another gesture like drag first.

This is my loadView of the ImageViewerController

- (void)loadView
{
    //Make the outer spaging scroll view
    CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
    scrollView.pagingEnabled = YES;
    scrollView.backgroundColor = [UIColor blackColor];
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.contentSize = [self contentSizeForPagingScrollView];
    scrollView.delegate = self;
    self.view = scrollView;
}

This is how I'm trying to set the content offset

#define myView (UIScrollView *)self.view

[myView setContentOffset:[self contentOffsetForIndex:index]];

[..]

- (CGPoint)contentOffsetForIndex:(NSUInteger)index
{
    return CGPointMake((index * (self.view.frame.size.width)), 0);
}
like image 849
Mike Avatar asked Jun 13 '11 22:06

Mike


1 Answers

Are you scrolling horizontally or vertically ? your offset logic
CGPointMake((index * (self.view.frame.size.width)), 0); is will move to 0 of Y axis. EDIT
I was a litte lazy writing the approach.
Here is the approach i adopt to find offset related issues:

a) programmatically offset is set by setContentOffset:, scrollRectToVisible, setFrame(of UIScrollView, internally calls SetContentOffset). First check all of these in your code, if they are correct.

b) print the Logs for offset being set in scrollViewDidScroll: method.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSLog(@" Offset = %@ ",NSStringFromCGPoint(scrollView.contentOffset));
}

This will help you identify the offset values being set (in most cases, the required offset is overriden by another call to setContentOffset: , some where in the code; lets say the current offset is (130,0) and you want to set the offset (300,0) it happens in steps (if animated) , you might get logs like
Offset = {130,0}
Offset = {190,0}
Offset = {220,0}
Offset = {270,0}
Offset = {300,0}

If there is some other call to setContentOffset(animated), lets say it sets offset to (0,0), the logs you get would look like
Offset = {130,0}
Offset = {190,0}
Offset = {90, 0}
Offset = {220,0}
Offset = {60,0}
Offset = {270,0}
Offset = {30,0}
Offset = {300,0}
Offset = {0,0}

If you notice the second pattern in Logs, you can be sure that there is some un intended call to setContentOffset.
3) Once you identify there is a call to unintended call to setContentOffset, try to find the source of it (setting breakpoint to setContentOffset might help), and can be addressed on a case to case basis. for ex:
_adjustContentOffsetIfNecessary, is an internal method called when frame is set for UIScrollView. This can be the reason (try applying previous offset after setting the frame).

Hope this helps (mee too , in getting the down vote removed :) )

like image 133
Tatvamasi Avatar answered Sep 17 '22 14:09

Tatvamasi