UIScrollView以编程方式滚动到底部

我怎样才能让UIScrollView滚动到我的代码底部? 或者以更通用的方式,对子视图的任何一点?

您可以使用UIScrollView的setContentOffset:animated:函数来滚动到内容视图的任何部分。 这里有一些代码将滚动到底部,假设你的scrollView是self.scrollView

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

希望有所帮助!

Swift版的接受答案,便于复制粘贴:

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

最简单的解决scheme

 [scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES]; 

将内容偏移设置为内容大小的高度是错误的:它将内容的底部滚动到滚动视图的顶部 ,从而看不见。

正确的解决方法是将内容的底部滚动到滚动视图的底部 ,像这样( sv是UIScrollView):

 CGSize csz = sv.contentSize; CGSize bsz = sv.bounds.size; if (sv.contentOffset.y + bsz.height > csz.height) { [sv setContentOffset:CGPointMake(sv.contentOffset.x, csz.height - bsz.height) animated:YES]; } 

只是现有答案的增强。

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

它也会考虑到底部embedded(如果你使用它来调整你的滚动视图时,键盘是可见的)

滚动到顶部

 - CGPoint topOffset = CGPointMake(0, 0); - [scrollView setContentOffset:topOffset animated:YES]; 

滚动到底部

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

Swift 2.2解决scheme,考虑到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

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

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

如果contentSize低于bounds呢?

对于Swift来说,它是:

 scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true) 

使用(可选)footerView和contentInset,解决scheme是:

 CGPoint bottomOffset = CGPointMake(0, _tableView.contentSize.height - tableView.frame.size.height + _tableView.contentInset.bottom); if (bottomOffset.y > 0) [_tableView setContentOffset: bottomOffset animated: YES]; 

一个快速的实现:

 extension UIScrollView { func scrollToBottom(animated animated: Bool) { if self.contentSize.height < self.bounds.size.height { return } let bottomOffset = CGPoint(x: 0, y: self.contentSize.height - self.bounds.size.height) self.setContentOffset(bottomOffset, animated: animated) } } 

使用UIScrollView的setContentOffset:animated: function滚动到Swift的底部。

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

valdyr,希望这会帮助你:

 CGPoint bottomOffset = CGPointMake(0, [textView contentSize].height - textView.frame.size.height); if (bottomOffset.y > 0) [textView setContentOffset: bottomOffset animated: YES]; 

类别来救援!

将其添加到某个共享的实用程序标头中:

 @interface UIScrollView (ScrollToBottom) - (void)scrollToBottomAnimated:(BOOL)animated; @end 

然后到该实用程序实现:

 @implementation UIScrollView(ScrollToBottom) - (void)scrollToBottomAnimated:(BOOL)animated { CGPoint bottomOffset = CGPointMake(0, self.contentSize.height - self.bounds.size.height); [self setContentOffset:bottomOffset animated:animated]; } @end 

然后将其实现在任何你喜欢的地方,例如:

 [[myWebView scrollView] scrollToBottomAnimated:YES]; 

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

 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]; } 

如果你不需要animation,这是有效的:

 [self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO]; 

虽然Matt解决scheme似乎对我来说正确的,你还需要考虑收集视图插入,如果有一个已经设置。

适应的代码将是:

 CGSize csz = sv.contentSize; CGSize bsz = sv.bounds.size; NSInteger bottomInset = sv.contentInset.bottom; if (sv.contentOffset.y + bsz.height + bottomInset > csz.height) { [sv setContentOffset:CGPointMake(sv.contentOffset.x, csz.height - bsz.height + bottomInset) animated:YES]; } 

解决scheme滚动到表的最后一项查看:

Swift 3:

 if self.items.count > 0 { self.tableView.scrollToRow(at: IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true) } 

当我尝试在self.tableView (iOS 4.1)上的UITableViewController使用它后,添加footerView后没有为我工作。 它滚动出境,显示黑屏。

替代scheme:

  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]; 
 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]; 

我发现contentSize并不真正反映文本的实际大小,所以当试图滚动到底部时,它会有点偏离。 确定实际内容大小的最好方法实际上是使用NSLayoutManagerusedRectForTextContainer:方法:

 UITextView *textView; CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size; 

要确定在UITextView实际显示的文本数量,可以通过从帧高度减去文本容器插入来计算它。

 UITextView *textView; UIEdgeInsets textInsets = textView.textContainerInset; CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom; 

那么就很容易滚动:

 // if you want scroll animation, use contentOffset UITextView *textView; textView.contentOffset = CGPointMake(textView.contentOffset.x, textSize - textViewHeight); // if you don't want scroll animation CGRect scrollBounds = textView.bounds; scrollBounds.origin = CGPointMake(textView.contentOffset.x, textSize - textViewHeight); textView.bounds = scrollBounds; 

一些数字可供参考,以表示不同的大小代表一个空的UITextView

 textView.frame.size = (width=246, height=50) textSize = (width=10, height=16.701999999999998) textView.contentSize = (width=246, height=33) textView.textContainerInset = (top=8, left=0, bottom=8, right=0) 

在迅速:

  if self.mainScroll.contentSize.height > self.mainScroll.bounds.size.height { let bottomOffset = CGPointMake(0, self.mainScroll.contentSize.height - self.mainScroll.bounds.size.height); self.mainScroll.setContentOffset(bottomOffset, animated: true) }