[英]Detect UIScrollview bottom reached
I have a UIScrollView with images and when the user scrolls to the end of the scrollview i want to update the content.我有一个带有图像的 UIScrollView,当用户滚动到滚动视图的末尾时,我想更新内容。 This is my code to detect when the bottom of the scrollview is reached:
这是我检测何时到达滚动视图底部的代码:
The code below is implemented in scrollViewDidScroll:
delegate下面的代码在
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];
}
My problem is that when the user scrolls to bottom, my function is called several times, but i want to call it only once.我的问题是,当用户滚动到底部时,我的函数被调用了几次,但我只想调用它一次。 I tried with imagesScrollView.contentOffset.y == scrollViewBottomOffset but it doesn't work and the function is not called
我尝试使用 imagesScrollView.contentOffset.y == scrollViewBottomOffset 但它不起作用并且未调用该函数
If you want to detect them in swift:如果您想快速检测它们:
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
}}
Carlos answer is better.卡洛斯的回答更好。
For Swift 4.x you must change method name:对于 Swift 4.x,您必须更改方法名称:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height) {
//bottom reached
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
if (bottomEdge >= scrollView.contentSize.height)
{
// we are at the end
}
}
Have you thought of adding a boolean.你有没有想过添加一个布尔值。 update it when the method is called for the first time and maybe when user scrolls back up.
在第一次调用该方法时更新它,也许当用户向上滚动时更新它。
Sometimes you will have to use +1 in the condition because the contentSize.height gives you a few decimals over, so if you use this, you avoid it...有时您将不得不在条件中使用 +1,因为 contentSize.height 给了您几个小数,所以如果您使用它,您可以避免它......
override func scrollViewDidScroll(scrollView: UIScrollView) {
if (scrollView.contentOffset.y + 1) >= (scrollView.contentSize.height - scrollView.frame.size.height) {
//bottom reached
}
}
实现scrollViewDidScroll:
并检查contentOffset
以达到终点
For Swift 4.5:对于 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
}
}
I used a mixed approach for this.我为此使用了混合方法。 Let me explain:
让我解释:
While your calculus is correct, the delegate your listening to is an overkill since scrollViewDidScroll
is called many times which can lead to performance issues.虽然您的微积分是正确的,但您收听的委托是一种矫枉过正,因为
scrollViewDidScroll
被多次调用,这可能会导致性能问题。 You should (as I did) use scrollViewDidEndDragging
and scrollViewDidEndDecelerating
which are called only once at the end of each of their respective events.您应该(像我一样)使用
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
}
}
func scrollViewDidEndDecelerating(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
}}
Make sure your view implementing the UIScrollViewDelegate确保您的视图实现了 UIScrollViewDelegate
MyView: UITableViewDelegate,UIScrollViewDelegate
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.