0

I'm a beginner at objective C learning to program, and also beginner at asking questions on this site, please bear with me.

I am currently trying to draw a column of boxes (UIControls) on the screen, and be able to scroll them upward or downward infinitely. So when one goes off the bottom of the screen its shifted to the bottom and reused.

I know there must be a lot of mistakes in the code. But the gist of what I am trying to do is: The boxes are all in an array (imArray). When a box scrolls off the bottom of the screen its taken off the end of the array, and inserted at the beginning. Then the box inserts itself graphically into the top of the column.

The first if statement deals with scrolling off the bottom of the screen, and it works fine. But the second if statement, where i try to do the opposite with similar code works only when i scroll slowly, when i scroll quickly the spacing between boxes becomes uneven, and sometimes a box just locks up on the screen and stops moving.

Any help is appreciated, and I will try to provide any more clarity that may be needed.

-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{

CGPoint pt = [touch locationInView:self];
int yTouchEnd = pt.y;
int yTouchChange = yTouchEnd - yTouchStart;

//iterate through all boxes in imArray
for(int i = 0; i < self.numberOfSections; i++)
{
    //1. get box
    STTimeMarker *label = self.imArray[i];
    //2. calculate new label transform
    label.transform = CGAffineTransformTranslate(label.startTransform, 0, yTouchChange);
    CGRect frame = label.frame;
    //3. if the box goes out of the screen on the bottom 
    if (frame.origin.y > [[UIScreen mainScreen]bounds].size.height)
    {

        //1. move box that left the screen to to beginning of array
        [self.imArray removeObjectAtIndex:i];
        [self.imArray insertObject:label atIndex:0];
        //2. get y value of box closest to top of screen. 
        STTimeMarker *labelTwo = self.imArray[1];
        CGRect frameTwo =labelTwo.frame;
        //3. put box that just left the screen in front of the box I just got y value of. 
        frame.origin.y = frameTwo.origin.y - self.container.bounds.size.height/self.numberOfSections;
        label.frame=frame;
     }

    //1. if the box goes out of the frame on the top
    // (box is 40 pixels tall)
    if (frame.origin.y < -40)
    {  
        [self.imArray removeObjectAtIndex:i];
        [self.imArray addObject:label];
        STTimeMarker *labelTwo = self.imArray[self.numberOfSections-1];
        CGRect frameTwo =labelTwo.frame;
        frame.origin.y = frameTwo.origin.y + self.container.bounds.size.height/self.numberOfSections;

        label.frame=frame;

    }
}

return YES;
}
yunyun
  • 1
  • This may not fit your exact need, but Apple has a [pretty good tutorial video here](https://developer.apple.com/videos/wwdc/2011/) that covers making scrollviews infinite. It's under _Advanced ScrollView Techniques_. – terrafirma9 Sep 08 '14 at 13:20

1 Answers1

0

If I understand what you are trying to do correctly, I think you want to come at this a different way. Your data model (the array) does not need to change. All that is changing as you scroll is the view, what is displaying on screen. The simplest way to achieve the appearance of an infinite scroll would be to use a UITableView and give it some large number of cells. Then your cellForRowAtIndexPath: method will return the cell for the correct position using the mod operator (%). Untested code:

- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
    return 99999;
}

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
    NSInteger moddedRow = indexPath.row % [self.imArray count];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kSomeIdentifierConst forIndexPath:[NSIndexPath indexPathForRow:moddedRow inSection:indexPath.section]];
    return [self configureCellWithData:self.imArray[moddedRow]];
}

This may not be sufficient for your purposes if you need true infinite scroll, but should work for most purposes.

colinbrash
  • 481
  • 2
  • 11