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
并不真正反映文本的实际大小,所以当试图滚动到底部时,它会有点偏离。 确定实际内容大小的最好方法实际上是使用NSLayoutManager
的usedRectForTextContainer:
方法:
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) }