3

I am trying to build an endless NSScrollView, i.e. a scroll view that can scroll infinitely in either direction. This is achieved by having a scroll view with fixed dimension which is 'recentered' once it gets too close to either edge, and keeping track of an additional endless offset that is updated when recentering. Apple even demonstrated this approach in a WWDC video for iOS, if I recall correctly.

On iOS everything is working. I perform the recentering logic in -scrollViewDidScroll: and it even works when the scrolling motion is decelerating without breaking the deceleration.

Now for the Mac version. Let me tell you that I'm fairly new to Mac development, so I may simply not have performed these operations in the correct places. I currently have the recentering logic in -reflectScrolledClipView:. When I perform the move operation immediately, however, the scroll view jumps exactly twice as far as I want it to (in this case, to 4000). If I delay the method slightly, it works just as expected.

- (void)reflectScrolledClipView:(NSClipView *)cView
{
    [self recenteringLogic];
    [super reflectScrolledClipView:cView];
}

- (void)recenteringLogic
{
    CGFloat offset = self.documentVisibleRect.origin.y;

    if (offset > 6000) {

        // This makes the scroll view jump to ~4000 instead of 5000.
        [self performSelector:@selector(move) withObject:nil];

        // This works, but seems wrong to me
//        [self performSelector:@selector(move) withObject:nil afterDelay:0.0];
    }
}

- (void)move
{
    [self.documentView scrollPoint:NSMakePoint(0, 4000)];
}

Any ideas on how I could achieve the behavior I want?

Christian Schnorr
  • 10,489
  • 8
  • 45
  • 81

2 Answers2

0

Try this:

- (void)scrollWheel:(NSEvent *)event {
    [super scrollWheel:event];
    [self recenteringLogic];
}

- (void)recenteringLogic
{
    NSRect rect = self.documentVisibleRect;
    if (rect.origin.y > 6000) {
            rect.origin.y = 4000;
            [self.contentView setBounds:rect];
    }
}

reflectScrolledClipView seemed to be clashing with scrollToPoint somehow, and it caused a stack overflows when used with the [self.contentView setBounds:rect]; method of scrolling.

Luke
  • 4,321
  • 1
  • 34
  • 56
  • Overriding `-scrollWheel:` results in the scroll view no longer scrolling at all. (it is layer backed in order to enable the smooth scrolling, [see @ WWDC](https://developer.apple.com/videos/wwdc/2013/?id=215). – Christian Schnorr Sep 12 '14 at 08:31
0

I ended up working with [self performSelector:@selector(move) withObject:nil afterDelay:0.0]; and haven't encountered any serious issues with it, despite it seeming a little wrong.

Christian Schnorr
  • 10,489
  • 8
  • 45
  • 81