Answers:
您可以使用UIScrollView的setContentOffset:animated:
功能滚动到内容视图的任何部分。假设您的scrollView是,这是一些滚动到底部的代码self.scrollView
:
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
希望有帮助!
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
contentSize
低于则无法正常工作bounds
。因此,它应该是这样的:scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
let bottomOffsetY = max(collectionView.contentSize.height - collectionView.bounds.height + collectionView.contentInset.bottom, 0)
易于接受的答案的Swift版本:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
scrollView.setContentOffset(bottomOffset, animated: true)
最简单的解决方案:
[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) 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];
它还会照顾底部的插图(以防您在可见键盘时使用它来调整滚动视图)
将内容偏移量设置为内容大小的高度是错误的:它将内容的底部滚动到滚动视图的顶部,因此不可见。
正确的解决方案是将内容的底部滚动到滚动视图的底部,如下所示(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];
}
if (sv.contentOffset.y + csz.height > bsz.height) {
吗?
setContentOffset:
是重要的命令。
快速实施:
extension UIScrollView {
func scrollToBottom(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)
}
}
用它:
yourScrollview.scrollToBottom(animated: true)
考虑contentInset
到Swift 2.2解决方案
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
在滚动之前
如果contentSize
低于bounds
呢?
对于Swift,它是:
scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
滚动到顶部
- 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];
似乎这里的所有答案都没有考虑到安全区域。从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)
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.adjustedContentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
contentOffset.x
):extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: contentOffset.x,
y: contentSize.height - bounds.height + adjustedContentInset.bottom)
setContentOffset(bottomOffset, animated: animated)
}
}
参考文献:
迅速:
您可以使用如下扩展名:
extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
setContentOffset(bottomOffset, animated: animated)
}
}
采用:
scrollView.scrollsToBottom(animated: true)
分类抢救!
将此添加到共享公用程序标头中的某个位置:
@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];
对于水平ScrollView
如果喜欢我的用户具有Horizontal ScrollView,并且想要滚动到它的末尾(在我的情况下,它最右边),则需要更改已接受答案的某些部分:
物镜
CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];
迅速
let rightOffset: CGPoint = CGPoint(x: self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, y: 0)
self.scrollView.setContentOffset(rightOffset, animated: true)
如果您以某种方式更改了scrollView contentSize(例如,将某些内容添加到scrollView内的stackView中),则必须scrollView.layoutIfNeeded()
在滚动之前调用它,否则它什么都不做。
例:
scrollView.layoutIfNeeded()
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
if(bottomOffset.y > 0) {
scrollView.setContentOffset(bottomOffset, animated: true)
}
确保可见内容底部的一种好方法是使用以下公式:
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];
}
而 Matt
解决方案对我来说似乎是正确的,但如果已经设置了集合视图插图,则还需要考虑集合视图插图。
修改后的代码将是:
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];
}
滚动到表格视图最后一项的解决方案:
迅捷3:
if self.items.count > 0 {
self.tableView.scrollToRow(at: IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)
}
添加后,当我尝试在UITableViewController
上使用它时,对我不起作用self.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];
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)
扩展UIScrollView以添加scrollToBottom方法:
extension UIScrollView {
func scrollToBottom(animated:Bool) {
let offset = self.contentSize.height - self.visibleSize.height
if offset > self.contentOffset.y {
self.setContentOffset(CGPoint(x: 0, y: offset), animated: animated)
}
}
}