Get UIScrollView to scroll to the top

2019-01-29 20:01发布

How do I make a UIScrollView scroll to the top?

13条回答
Juvenile、少年°
2楼-- · 2019-01-29 20:02

In iOS7 I had trouble getting a particular scrollview to go to the top, which worked in iOS6, and used this to set the scrollview to go to the top.

[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
查看更多
3楼-- · 2019-01-29 20:09

Use setContentOffset:animated:

[scrollView setContentOffset:CGPointZero animated:YES];
查看更多
来,给爷笑一个
4楼-- · 2019-01-29 20:09

To fully replicate the status bar scrollToTop behavior we not only have to set the contentOffset but also want to make sure the scrollIndicators are displayed. Otherwise the user can quickly get lost.

The only public method to accomplish this is flashScrollIndicators. Unfortunately, calling it once after setting the contentOffset has no effect because it's reset immediately. I found it works when doing the flash each time in scrollViewDidScroll:.

// define arbitrary tag number in a global constants or in the .pch file
#define SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG 19291

- (void)scrollContentToTop {
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];

    self.scrollView.tag = SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.scrollView.tag = 0;
    });
}

In your UIScrollViewDelegate (or UITable/UICollectionViewDelegate) implement this:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
        [scrollView flashScrollIndicators];
    }
}

The hide delay is a bit shorter compared to the status bar scrollToTop behavior but it still looks nice.

Note that I'm abusing the view tag to communicate the "isScrollingToTop" state because I need this across view controllers. If you're using tags for something else you might want to replace this with an iVar or a property.

查看更多
\"骚年 ilove
5楼-- · 2019-01-29 20:12

iOS 11 and above

try to work with the new adjustedContentInset.

For example (scroll to the top):

var offset = CGPoint(
    x: -scrollView.contentInset.left, 
    y: -scrollView.contentInset.top)

if #available(iOS 11.0, *) {
    offset = CGPoint(
        x: -scrollView.adjustedContentInset.left, 
        y: -scrollView.adjustedContentInset.top)    
}

scrollView.setContentOffset(offset, animated: true)

Even if you use prefersLargeTitles, safe area etc.

查看更多
Rolldiameter
6楼-- · 2019-01-29 20:14

Here is a Swift extension that makes it easy:

extension UIScrollView {
    func scrollToTop() {
        let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
        setContentOffset(desiredOffset, animated: true)
   }
}

Usage:

myScrollView.scrollToTop()
查看更多
ら.Afraid
7楼-- · 2019-01-29 20:15

Swift 3.0.1 version of rob mayoff's answer :

self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
查看更多
登录 后发表回答