UIScrollView: single tap scrolls it to top

2020-02-29 03:35发布

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.

5条回答
▲ chillily
2楼-- · 2020-02-29 04:13

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 (i.e. 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. :)

查看更多
We Are One
3楼-- · 2020-02-29 04:21

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.

查看更多
Ridiculous、
4楼-- · 2020-02-29 04:21

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).

查看更多
我想做一个坏孩纸
5楼-- · 2020-02-29 04:22

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.

查看更多
Anthone
6楼-- · 2020-02-29 04:24

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;
    }
}
查看更多
登录 后发表回答