8

I have a custom horizontal collection view that has 1 row and I want to add pull to refresh functionality which, by default, appears above my row of cells. I would like the user to be able to pull the collection view from left to right to activate the UIRefreshControl. Any ideas?

Thanks in advance.

markdorison
  • 139,374
  • 27
  • 55
  • 71
CppChase
  • 901
  • 12
  • 25

3 Answers3

7

Basically the response above tells you how to do in Objective-C a load more in a UICollectionView. However, I believe the question was how to do pull to refresh horizontally on that component.

I don't think you can add a UIRefreshControl horizontally but taking into consideration the previous code and making a conversion to Swift I came up with the following one

DON'T FORGET TO SET YOUR UICollectionView bounce property TO TRUE

func scrollViewDidScroll(scrollView: UIScrollView) {
    let offset = scrollView.contentOffset
    let inset = scrollView.contentInset
    let y: CGFloat = offset.x - inset.left
    let reload_distance: CGFloat = -75
    if y < reload_distance{
        scrollView.bounces = false
        UIView.animateWithDuration(0.3, animations: { () -> Void in
             scrollView.setContentOffset(CGPointMake(0, 0), animated: false)
        }, completion: { (Bool) -> Void in
             scrollView.bounces = true
        })
    }
}

Also and in order to avoid issues with the continuous pulling I added some code to remove the bouncing temporarily, animate de scroll back to the right and then enabling the bouncing again. That will give you the same effect as the UIRefreshControl.

Finally, if you want to have a loading icon my suggestion is to add it behind the controller so when you pull you can see it behind

Julio Bailon
  • 3,735
  • 2
  • 33
  • 34
  • This code is outdated. I get the error: `'CGPointMake' is unavailable in Swift` It has been explicitly marked unavailable. Any ideas? – Angel Garcia Aug 03 '18 at 23:32
  • 1
    @AngelGarcia CGPointMake has been replaced by CGPoint(x: , y:). In this case would be CGPoint(x: 0, y: 0). Let me know if that helps – Julio Bailon Aug 21 '18 at 16:57
  • I suppose the better way would be to place this code into `scrollViewDidEndDragging` func cuz otherwise the block in if statement will be called multiple times. Also then better approach would be to call your update function inside if statement block with Dispatch after. Something like that: `DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.presenter.refresh(section: section) }` – Serj Rubens Feb 25 '21 at 15:06
2

Just adding the Obj-C version of Julio Bailon's answer, which works for pulling the collectionView from its Top i.e. Left to Right

    CGPoint offset = scrollView.contentOffset;
    CGRect bounds = scrollView.bounds;
    CGSize size = scrollView.contentSize;
    UIEdgeInsets inset = scrollView.contentInset;
    float y = offset.x - inset.left;
    float h = size.width;


    float reload_distance = -75; //distance for which you want to load more
    if(y < reload_distance) {
        // write your code getting the more data
        NSLog(@"load more rows");

    }
Hyder
  • 1,163
  • 2
  • 13
  • 37
1

For this you need to implement the UIScrollViewDelegate method

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
     CGPoint offset = scrollView.contentOffset;
     CGRect bounds = scrollView.bounds;
     CGSize size = scrollView.contentSize;
     UIEdgeInsets inset = scrollView.contentInset;
     float y = offset.x + bounds.size.width - inset.right;
     float h = size.width;


     float reload_distance = 75; //distance for which you want to load more
     if(y > h + reload_distance) {
        // write your code getting the more data
        NSLog(@"load more rows");

     }
 }
Nitin
  • 1,383
  • 10
  • 19
  • Thanks for the code above. Just want to mention it works for when you want to load more data after reaching the end of your scrolling tableview/collectionview, not top. – Hyder Jan 30 '17 at 11:37