16

I want to scroll like that 1 2 3 1 2 3

I have some buttons suppose 10 which i want to show on endless scroll.

 numbercolors=[[NSMutableArray alloc] init];

 //total count of array is  49 

 numbercolors = [NSMutableArray arrayWithObjects:@"25",@"26",@"27",@"28",@"29",@"31",@"32",@"33",@"34",@"35", @"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",@"35", @"0",@"1",@"2",@"3",nil];

  int x=2500;

for (NSInteger index = 0; index < [numbercolors count]; index++)
{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

    button.frame = CGRectMake(x ,0,29.0,77.0);

    button.tag = index;

    [button setTitle:[numbercolors objectAtIndex:index] forState:UIControlStateNormal];

    [button addTarget:self action:@selector(didTapButton:) 

    forControlEvents:UIControlEventTouchUpInside];

    [coloringScroll addSubview:button];

    x=x+70+29;
}
 [coloringScroll setContentSize:CGSizeMake(5000+ (29+70)*[numbercolors count], 1)];

 [coloringScroll setContentOffset:CGPointMake(2500+(29+70)*11, 0)];

This is my code for make butttons on scrollview.

How can I set in - (void)scrollViewDidEndDecelerating:(UIScrollView *)sender this method for infinite scroll.

Forge
  • 6,538
  • 6
  • 44
  • 64
virantporwal
  • 989
  • 2
  • 6
  • 26
  • http://stackoverflow.com/questions/8038293/infinite-uiscrollview – peko Oct 09 '13 at 10:00
  • 1
    If you want it truly "infinite" then you probably want to "tile" your display, such that "tiles" are created at one end and removed at the other. Kind of like how UITableView is done. – Hot Licks Jan 06 '14 at 03:43

8 Answers8

8

Just need to do set setContentOffset count

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.x > 2500+(29+70)*4 + ((29+70)*36)) {
        [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x-((29+70)*36),  0)];  
    }
    if (scrollView.contentOffset.x < 2500+(29+70)*4){
       [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x+((29+70)*36), 0)];
    }
}
Julian
  • 9,299
  • 5
  • 48
  • 65
virantporwal
  • 989
  • 2
  • 6
  • 26
7

Main idea is to reposition your scrollview back to some constant value, when it has been scrolled to some value and then auto-reposition your "1" , "2", "3" items correctly.

For example - You would have scrollview with contentwidth 5000. By default You set it to position 2500.

then You simply check in - (void)scrollViewDidCScroll:(UIScrollView *)scrollview - if scrollview.contentoffset.x > 3500 - then decrease it's position to scrollview.contentoffset.x -=1000;

and the same about other side. This will result in infinite scrolling.

But content will not follow. So - You would need to implement extra content offset value checking to reorder and reposition correctly "1", "2", "3", items.

I usually use 3 elements and then dynamically preload necessary gallery image for them.

If You don't want to re-invent the "wheel" , check out these solutions:

https://www.cocoacontrols.com/controls/dmcircularscrollview

https://www.cocoacontrols.com/controls/infinitescrollview

https://www.cocoacontrols.com/controls/iainfinitegridview

Guntis Treulands
  • 4,764
  • 2
  • 50
  • 72
  • i think i have problem with this because i am using small images and dont know how can i set contentoffset.Just because of that i put all code here ..... – virantporwal Oct 09 '13 at 10:31
  • sorry but i know i need to set contentoffset,main point is how? – virantporwal Oct 09 '13 at 10:33
  • scrollview content offset can be changed like this: [scrollview setContentOffset:CGPointMake(2500, 0)]; – Guntis Treulands Oct 09 '13 at 10:52
  • see actually my objects(in array) are not fixed (how much show in first time and how much are reaming)so for this how can i set contentoffset for my next view.if i have an image with 320 width then i will increase contentoffset with multiple of 320 but here i cant. – virantporwal Oct 09 '13 at 10:57
  • Simply check out given examples - it will be much easier that way + You will see the code and learn how it is done. – Guntis Treulands Oct 09 '13 at 11:20
  • How so? Provided links contains fully working infinite scrollviews! – Guntis Treulands Oct 09 '13 at 12:00
  • that is the example of paging and i want scroll both are different,that is the resign – virantporwal Oct 09 '13 at 12:03
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/38875/discussion-between-virantporwal-and-guntis-treulands) – virantporwal Oct 09 '13 at 12:08
3

You can check out this solution based on Apple StreetScroller iOS sample code:

https://github.com/gblancogarcia/GBInfiniteScrollView

I hope it helps!

2

I have written an infinite rolling UIscrollView subclass which accomplishes this task. It is based on the Apple StreetScroller sample. You simply provide it with your button titles and whether you want a horizontal or vertical scroll. You can also set many other options. It is posted with documentation and a sample project on my github. Here is the link...

http://github.com/ninefifteen/SSRollingButtonScrollView

ninefifteen
  • 931
  • 1
  • 10
  • 16
1

This is an old question, but I'm writing this to help whom searching for same solution. Suppose that we wish to infinitely loop through 3 items(cells) - C0, C1, C2, we can generate dummy cells at the left and right side of center cells, the result as follows,

C0 C1 C2 [C0 C1 C2] C0 C1 C2

Cells in bracket are cells we see through device screen, and if we scroll to left,

C0 [C1 C2 C0] C1 C2 C0 C1 C2

at this moment, force contentOffset to point right side of given dummy cells,

C0 [C1 C2 C0] C1 C2 C0 C1 C2 -> C0 C1 C2 C0 [C1 C2 C0] C1 C2

Since it's time consuming job to implement this seamlessly, I recommend my solution below.

https://github.com/DragonCherry/HFSwipeView

If you just wanna check how it works, click link below and "tap to play".

https://www.cocoacontrols.com/controls/hfswipeview

0

I've implemented an infinite scroller in swift.
It's inspired by apple StreetScroller example

I know is not perfect yet, but I think is a god start point.

InfiniteVerticalScroller

Luca Davanzo
  • 21,000
  • 15
  • 120
  • 146
0

For right infinite scroll you can use -

        let rightOffset = CGPoint.init(x: (scrollView.contentSize.width) - (scrollView.bounds.width), y: 0)
    UIView.animate(withDuration: 3.0,
                   delay: 0.0,
                   options: [.curveLinear, .repeat],
                   animations: { () -> Void in
                    self.scrollView.contentOffset = rightOffset

    }, completion: { (finished: Bool) -> Void in
        self.scrollView.setContentOffset(.init(x: 0, y: self.scrollView.contentOffset.y), animated: false)
    })
niku
  • 472
  • 3
  • 12
0

The answers provided here are good but if you're still not satisfied and looking for a different approach here's what I've done.

The main idea is to update the number of cells whenever you reach the cell before the last one. Each time you increase the number of items by 1 so it gives the illusion of infinite scrolling. To do that we can utilize scrollViewDidEndDecelerating(_ scrollView: UIScrollView) function to detect when the user has finished scrolling, and then update the number of items in the collection view. Here's a code snippet to achieve that:

class InfiniteCarouselView: UICollectionView {

    var data: [Any] = []

    private var currentIndex: Int?
    private var currentMaxItemsCount: Int = 0
    // Set up data source and delegate
}

extension InfiniteCarouselView: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // Set the current maximum to a number above the maximum count by 1
        currentMaxItemsCount = max(((currentIndex ?? 0) + 1), data.count) + 1
        return currentMaxItemsCount

    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
        let row = indexPath.row % data.count
        let item = data[row]
        // Setup cell
        return cell
    }
}

extension InfiniteCarouselView: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
    }

    // Detect when the collection view has finished scrolling to increase the number of items in the collection view
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        // Get the current index. Note that the current index calculation will keep changing because the collection view is expanding its content size based on the number of items (currentMaxItemsCount)
        currentIndex = Int(scrollView.contentOffset.x/scrollView.contentSize.width * CGFloat(currentMaxItemsCount))
        // Reload the collection view to get the new number of items
        reloadData()
    }
}

Pros

  • Straightforward implementation
  • No use of Int.max (Which in my own opinion is not a good idea)
  • No use of an arbitrary number (Like 50 or something else)
  • No change or manipulation of the data
  • No manual update of the content offset or any other scroll view attributes

Cons

  • Paging should be enabled (Although the logic can be updated to support no paging)
  • Need to maintain a reference for some attributes (current index, current maximum count)
  • Need to reload the collection view on each scroll end (Not a big deal if the visible cells are minimal). This might affect you drastically if you're loading something asynchronously without caching (Which is a bad practice and data should be cached outside the cells)
  • Doesn't work if you want infinite scroll in both directions
Santina
  • 52
  • 1
  • 6