检测 UIScrollview 底部到达
Posted
技术标签:
【中文标题】检测 UIScrollview 底部到达【英文标题】:Detect UIScrollview bottom reached 【发布时间】:2013-12-14 13:26:41 【问题描述】:我有一个带有图像的 UIScrollView,当用户滚动到滚动视图的末尾时,我想更新内容。这是我检测何时到达滚动视图底部的代码:
下面的代码在scrollViewDidScroll:
delegate中实现
CGFloat scrollViewHeight = imagesScrollView.bounds.size.height;
CGFloat scrollContentSizeHeight = imagesScrollView.contentSize.height;
CGFloat bottomInset = imagesScrollView.contentInset.bottom;
CGFloat scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight;
if(imagesScrollView.contentOffset.y > scrollViewBottomOffset)
[imagesView addSubview:imagesBottomLoadingView];
[self downloadImages];
我的问题是当用户滚动到底部时,我的函数被调用了几次,但我只想调用一次。我尝试使用 imagesScrollView.contentOffset.y == scrollViewBottomOffset 但它不起作用并且没有调用该函数
【问题讨论】:
添加条件标志以过滤掉多余的调用,例如 if (imagesView has child imagesBottomLoadingView) 好的,这很容易,但我没想到。谢谢! 【参考方案1】:如果你想快速检测它们:
override func scrollViewDidScroll(scrollView: UIScrollView)
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height))
//reach bottom
if (scrollView.contentOffset.y < 0)
//reach top
if (scrollView.contentOffset.y >= 0 && scrollView.contentOffset.y < (scrollView.contentSize.height - scrollView.frame.size.height))
//not top and not bottom
【讨论】:
如果视图最初加载,“到达底部”部分也是如此。正如@Proveme007 指出的那样,使用scrollViewDidEndDecelerating
method 可以避免这种情况。此外,使用这种方法不需要处理额外的标志。【参考方案2】:
卡洛斯的答案更好。
对于 Swift 4.x,您必须更改方法名称:
func scrollViewDidScroll(_ scrollView: UIScrollView)
if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height)
//bottom reached
【讨论】:
【参考方案3】:- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
if (bottomEdge >= scrollView.contentSize.height)
// we are at the end
【讨论】:
【参考方案4】:有时您必须在条件中使用 +1,因为 contentSize.height 会给您小数点后几位,所以如果您使用它,请避免使用它...
override func scrollViewDidScroll(scrollView: UIScrollView)
if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height)
//bottom reached
【讨论】:
【参考方案5】:你有没有想过添加一个布尔值。在第一次调用该方法时更新它,并且可能在用户向上滚动时更新它。
【讨论】:
【参考方案6】:我为此使用了混合方法。让我解释一下:
虽然您的微积分是正确的,但您收听的委托是多余的,因为 scrollViewDidScroll
被多次调用,这可能会导致性能问题。你应该(和我一样)使用scrollViewDidEndDragging
和scrollViewDidEndDecelerating
,它们在各自的事件结束时只调用一次。
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
// Scrolling acceleration didn't continue after the finger was lifted
if !decelerate
executeActionAtTheEnd(of: scrollView)
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
executeActionAtTheEnd(of: scrollView)
private func executeActionAtTheEnd(of scrollView: UIScrollView)
if scrollView.contentOffset.y + 1 >= (scrollView.contentSize.height - scrollView.frame.size.height)
// Do here whatever you want when end of scrolling is reached
【讨论】:
【参考方案7】:实现scrollViewDidScroll:
并检查contentOffset
是否到达终点
【讨论】:
好的...请提及您已在scrollViewDidScroll:
delegate 中编写代码以避免任何混淆【参考方案8】:
对于 Swift 4.5:
func scrollViewDidScroll(_ scrollView: UIScrollView)
let scrollViewHeight = scrollView.frame.size.height
let scrollContentSizeHeight = scrollView.contentSize.height
let scrollOffset = scrollView.contentOffset.y
if (scrollOffset == 0)
// then we are at the top
print("then we are at the top")
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
print("then we are at the end")
// then we are at the end
【讨论】:
你应该用一些解释来围绕你的答案。那真的会提高它的质量。 问题是,当您使用内容插入和/或调整后的插入时,这不起作用,这在使用 iphone x 及其安全区域时是正常的。以上是关于检测 UIScrollview 底部到达的主要内容,如果未能解决你的问题,请参考以下文章
scrollViewDidScroll(_ scrollView: UIScrollView) 到达底部后如何保持 UIButton 浮动?