UIScrollView以编程方式滚动到底部

nic*_*ico 287 objective-c uiscrollview ios swift

如何UIScrollView在代码中滚动到底部?或者以更通用的方式,到子视图的任何一点?

Ben*_*tow 611

您可以使用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];
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!

  • 你没有考虑到插入物.我想你应该更喜欢这个bottomOffset:`CGPoint bottomOffset = CGPointMake(0,self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);` (69认同)
  • 你可能想以下滚动,而不是出滚动视图的底部,:CGPoint bottomOffset = CGPointMake(0,[self.scrollView contentSize] .height - self.scrollView.frame.size.height); (24认同)
  • 如果 `contentSize` 低于 `bounds`,它将无法正常工作。所以它应该是这样的:`scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animation: true)` (3认同)

Esq*_*uth 117

轻松复制粘贴的Swift版本接受的答案:

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

  • 哦,我们都喜欢培根,披萨和复制粘贴. (52认同)
  • 你需要检查scrollView.contentSize.height - scrollView.bounds.size.height> 0否则你会得到奇怪的结果 (9认同)
  • bottomOffset应该是let而不是var在你的例子中. (3认同)
  • 当您拥有新的导航栏时,此解决方案并不完美。 (3认同)

Hai*_* Hw 52

最简单的解决方案

[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES];
Run Code Online (Sandbox Code Playgroud)

  • 为什么不只是: [scrollviewscrollRectToVisible:CGRectMake(0,scrollview.contentSize.height,1,1)animated:YES]; (2认同)

viv*_*241 26

只是对现有答案的增强.

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

它还会处理底部插图(如果您在键盘可见时使用它来调整滚动视图)


mat*_*att 19

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

正确的解决方案是将内容的底部滚动到滚动视图的底部,就像这样(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];
}
Run Code Online (Sandbox Code Playgroud)


dua*_*uan 15

一个很好的实施:

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)
  }
}
Run Code Online (Sandbox Code Playgroud)

你可以这样调用扩展名:

yourScrollview.scrollToBottom(animated: true)
Run Code Online (Sandbox Code Playgroud)


onm*_*133 15

一个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)
Run Code Online (Sandbox Code Playgroud)

这应该是一个扩展

extension UIScrollView {

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

请注意,您可能需要检查是否bottomOffset.y > 0在滚动之前


小智 13

滚动到顶部

- CGPoint topOffset = CGPointMake(0, 0);
- [scrollView setContentOffset:topOffset animated:YES];
Run Code Online (Sandbox Code Playgroud)

滚动到底部

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


Bar*_*zyk 12

如果contentSize低于bounds

对于Swift来说:

scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
Run Code Online (Sandbox Code Playgroud)


nic*_*ico 7

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

[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
Run Code Online (Sandbox Code Playgroud)


Hon*_*ang 7

看起来这里的所有答案都没有考虑安全区域。从 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)
Run Code Online (Sandbox Code Playgroud)
  • 目标-C
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.adjustedContentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
Run Code Online (Sandbox Code Playgroud)
  • Swift 扩展(这保持原来的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)
    }
}
Run Code Online (Sandbox Code Playgroud)

参考:


小智 7

如果您以某种方式更改了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)
}
Run Code Online (Sandbox Code Playgroud)


小智 6

使用UIScrollView的setContentOffset:animated:函数滚动到Swift的底部.

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


小智 6

迅速:

你可以使用这样的扩展:

extension UIScrollView {
    func scrollsToBottom(animated: Bool) {
        let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
        setContentOffset(bottomOffset, animated: animated)
    }
}
Run Code Online (Sandbox Code Playgroud)

用:

scrollView.scrollsToBottom(animated: true)
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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