简体   繁体   中英

UIScrollView: single tap scrolls it to top

I have the UIScrollView with pagingEnabled set to YES, and programmatically scroll its content to bottom:

CGPoint contentOffset = scrollView.contentOffset;
contentOffset.y = scrollView.contentSize.height - scrollView.frame.size.height;
[scrollView setContentOffset:contentOffset animated:YES];

it scrolls successfully, but after that, on single tap its content scrolls up to offset that it has just before it scrolls down. That happens only when I programmaticaly scroll scrollView's content to bottom and then tap. When I scroll to any other offset and then tap, nothing is happened.

That's definitely not what I'd like to get. How that should be fixed?

Much thanks in advance!

Timur.

This small hack prevents the UIScrollView from scrolling when tapped. Looks like this is happening when the scroll view has paging enabled.

In your UIScrollView delegate add this method:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    scrollView.pagingEnabled = self.scrollView.contentOffset.x < (self.scrollView.contentSize.width - self.scrollView.frame.size.width);
}

This disables the paging when the scroll view reaches the right end in horizontal scrolling (my use case, you can adapt it to other directions easily).

I just figured out what causes this problem, and how to avoid it. If you having pagingEnabled set to YES on a scroll view, you must set the contentOffset to be a multiple of the scroll view's visible size (ie you should be on a paging boundary).

Concrete example:

If your scroll view was (say) 460 pixels high with a content area of 920, you would need to set the content offset to EITHER 0 or 460 if you want to avoid the "scroll to beginning on tap" problem.

As a bonus, the end result will probably look better since your scroll view will be aligned with the paging boundaries. :)

The following workaround did help (assume that one extends UIScrollView with a category, so 'self' refers to its instance):

-(BOOL) scrolledToBottom
{
    return (self.contentSize.height <= self.frame.size.height) ||
           (self.contentOffset.y == self.contentSize.height - self.frame.size.height);
}

Then, one should sometimes turn pagingEnabled off, just at the position where scroll view reaches its bottom. In the delegate (pagingEnabled is initialy on of course, since the problem occurs only when it is enabled):

-(void) scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (scrollView.pagingEnabled == YES)
    {
        if ([scrollView scrolledToBottom] == YES)
            scrollView.pagingEnabled = NO;
    }
    else
    {
        if ([scrollView scrolledToBottom] == NO)
            scrollView.pagingEnabled = YES;
    }
}

This seems to be a bug:

UIScrollView doesn't remember the position

I have tested this on iOS 4.2 (Simulator) and the issue remains.

When scrolling a ScrollView I would suggest using

[scrollView scrollRectToVisible:CGRectMake(0,0,1,1) animated:YES];

Where the rect is the position you're after. (In this case the rect would be the top of the scrollview).

Changing the content offset is not the correct way of scrolling a scrollview.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM