views:

92

answers:

1

This seems like such a trivial question to ask, but it's been vexing me for a while.

I have a window which contains a scroll view. Typically, the scroll view has a documentView that is vertically larger than the clip view, so you get a vertical scroller to see all the content inside the scroll view.

When I resize the window, I recalculate the size of the content in the scroll view's documentView (because the scroll view can get thinner, which might make it necessary for the documentView to grow in height). A side effect, however, is that when resizing the window, the documentView keeps the bottom visible edge flush with the bottom edge of the clip view (that is, it makes sure that the last line of text is always visible). This is a weird effect, because typically, windows keep the top visible edge of the document view flush with the top edge of the clip view (that is, the topmost line of text in the document view remains pinned to the top).

So, my initial thought to fix this problem was just to implement a windowDidResize: or windowWillResize:toSize: notification, note the delta between the old window frame's height and the new height, and then simply scroll the scroll view that much in order to keep the top line of the scroll view pinned to the top.

However, for some reason, this doesn't seem to work. It almost works, but some resizing deltas seem to be a pixel off, and if you resize the window fast enough, it sometimes is ~10 pixels off. So the effect is that the top line of the scroll view is almost pinned to the top, but not quite, and it's distracting.

Is there a better way to do this? Here's the relevant code:

- (void)windowDidResize:(NSNotification *)notification;
{
    if ([notification object] == mainWindow) {
        CGFloat currentWindowHeight = [mainWindow frame].size.height;

        // previousWindowHeight is an ivar
        NSNumber *heightDeltaNum = [NSNumber numberWithFloat:(currentWindowHeight - previousWindowHeight)];
        previousWindowHeight = currentWindowHeight;
        [[NSNotificationCenter defaultCenter] postNotificationName:@"AFSnapScrollView" object:heightDeltaNum];
    }
}

- (void)snapScrollViewNotification:(NSNotification *)theNotification;
{
    [self snapScrollView];

    NSNumber *heightDeltaNum = [theNotification object];

    CGFloat newY = [[tagScrollView documentView] visibleRect].origin.y - [heightDeltaNum floatValue];
    NSPoint pointToScroll = NSMakePoint(0,newY);
    [[tagScrollView documentView] scrollPoint:pointToScroll];
}

- (void)snapScrollView;
{

    [...]

    // adjust the view frame
    [[tagScrollView documentView] setFrame:NSMakeRect(0, 0, existingDocumentFrame.size.width, newDocumentViewHeight)];

    [...]

}
A: 

Your document view needs to override the -(BOOL)isFlipped method and return YES.

Chris Suter
Hm, did not realize that affected behavior of scroll views. Works perfectly, does exactly what I want (once I modified parts of the snapScrollView method to adjust for the flipped coordinates). Thanks very much!
Simone Manganelli