Get UIScrollView to scroll to the top

2019-01-29 20:01发布

How do I make a UIScrollView scroll to the top?

13条回答
该账号已被封号
2楼-- · 2019-01-29 20:18

UPDATE FOR iOS 7

[self.scrollView setContentOffset:
    CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];

ORIGINAL

[self.scrollView setContentOffset:CGPointZero animated:YES];

or if you want to preserve the horizontal scroll position and just reset the vertical position:

[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
    animated:YES];
查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-29 20:18

It's very common when your navigation bar overlaps the small portion of the scrollView content and it looks like content starts not from the top. For fixing it I did 2 things:

  • Size Inspector - Scroll View - Content Insets --> Change from Automatic to Never.
  • Size Inspector - Constraints- "Align Top to" (Top Alignment Constraints)- Second item --> Change from Superview.Top to Safe Area.Top and the value(constant field) set to 0

Content insets - Never Align ScrolView.Top to Safe Area.Top

查看更多
我命由我不由天
4楼-- · 2019-01-29 20:21

Scroll to top for UITableViewController, UICollectionViewController or any UIViewController having UIScrollView

extension UIViewController {

  func scrollToTop(animated: Bool) {
    if let tv = self as? UITableViewController {
        tv.tableView.setContentOffset(CGPoint.zero, animated: animated)
    } else if let cv = self as? UICollectionViewController{
        cv.collectionView?.setContentOffset(CGPoint.zero, animated: animated)
    } else {
        for v in view.subviews {
            if let sv = v as? UIScrollView {
                sv.setContentOffset(CGPoint.zero, animated: animated)
            }
        }
    }
  }
}
查看更多
欢心
5楼-- · 2019-01-29 20:26

For Swift 4

scrollView.setContentOffset(.zero, animated: true)
查看更多
Bombasti
6楼-- · 2019-01-29 20:27

Answer for Swift 2.0/3.0/4.0 and iOS 7+:

let desiredOffset = CGPoint(x: 0, y: -self.scrollView.contentInset.top)
self.scrollView.setContentOffset(desiredOffset, animated: true)
查看更多
Deceive 欺骗
7楼-- · 2019-01-29 20:28

I think I have an answer that should be fully compatible with iOS 11 as well as prior versions (for vertical scrolling)

This takes into account the new adjustedContentInset and also accounts for the additional offset required when prefersLargeTitles is enabled on the navigationBar which appears to require an extra 52px offset on top of whatever the default is

This was a little tricky because the adjustedContentInset changes depending on the titleBar state (large title vs small title) so I needed to check and see what the titleBar height was and not apply the 52px offset if its already in the large state. Couldn't find any other method to check the state of the navigationBar so if anyone has a better option than seeing if the height is > 44.0 I'd like to hear it

func scrollToTop(_ scrollView: UIScrollView, animated: Bool = true) {
    if #available(iOS 11.0, *) {
        let expandedBar = (navigationController?.navigationBar.frame.height ?? 64.0 > 44.0)
        let largeTitles = (navigationController?.navigationBar.prefersLargeTitles) ?? false
        let offset: CGFloat = (largeTitles && !expandedBar) ? 52: 0
        scrollView.setContentOffset(CGPoint(x: 0, y: -(scrollView.adjustedContentInset.top + offset)), animated: animated)
    } else {
        scrollView.setContentOffset(CGPoint(x: 0, y: -scrollView.contentInset.top), animated: animated)
    }
}

Inspired by Jakub's solution

查看更多
登录 后发表回答