我怎么能让一个UIScrollView滚动到我的代码底部?或者用更一般的方式,到子视图的任意点?


当前回答

CGFloat yOffset = scrollView.contentOffset.y;

CGFloat height = scrollView.frame.size.height;

CGFloat contentHeight = scrollView.contentSize.height;

CGFloat distance = (contentHeight  - height) - yOffset;

if(distance < 0)
{
    return ;
}

CGPoint offset = scrollView.contentOffset;

offset.y += distance;

[scrollView setContentOffset:offset animated:YES];

其他回答

Swift 2.2解决方案,考虑了contentInset

let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)

这应该是一个扩展

extension UIScrollView {

  func scrollToBottom() {
    let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
    setContentOffset(bottomOffset, animated: true)
  }
}

注意,您可能想检查bottomOffset。滚动前的Y > 0

对我没用,当我在UITableViewController上使用它时。tableView (iOS 4.1),添加footerView后。它滚动出边界,显示黑屏。

可选择的解决方案:

 CGFloat height = self.tableView.contentSize.height; 

 [self.tableView setTableFooterView: myFooterView];
 [self.tableView reloadData];

 CGFloat delta = self.tableView.contentSize.height - height;
 CGPoint offset = [self.tableView contentOffset];
 offset.y += delta;

 [self.tableView setContentOffset: offset animated: YES];

我还发现了另一种有用的方法,在这种情况下,你正在使用UITableview(这是UIScrollView的子类):

[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

看起来这里所有的答案都没有考虑到安全区域。 从iOS 11开始,iPhone X引入了安全区域。这可能会影响scrollView的contentInset。

对于iOS 11及以上版本,正确地滚动到底部,包括插入的内容。你应该使用adjustedContentInset而不是contentInset。检查这段代码:

迅速:

let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.adjustedContentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)

objective - c

CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.adjustedContentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];

Swift扩展(这保留了原来的contenttoffset .x):

extension UIScrollView {
    func scrollsToBottom(animated: Bool) {
        let bottomOffset = CGPoint(x: contentOffset.x,
                                   y: contentSize.height - bounds.height + adjustedContentInset.bottom)
        setContentOffset(bottomOffset, animated: animated)
    }
}

引用:

adjustedContentInset

确保内容底部可见的一个好方法是使用以下公式:

contentOffsetY = MIN(0, contentHeight - boundsHeight)

这确保内容的下边缘始终位于视图的下边缘或高于视图的下边缘。MIN(0,…)是必需的,因为UITableView(可能还有UIScrollView)确保当用户试图通过可见的抓取contentOffsetY = 0来滚动时,contentOffsetY >= 0。对于用户来说,这看起来很奇怪。

实现这个的代码是:

UIScrollView scrollView = ...;
CGSize contentSize = scrollView.contentSize;
CGSize boundsSize = scrollView.bounds.size;
if (contentSize.height > boundsSize.height)
{
    CGPoint contentOffset = scrollView.contentOffset;
    contentOffset.y = contentSize.height - boundsSize.height;
    [scrollView setContentOffset:contentOffset animated:YES];
}