Закрепление представления документа NSScrollView при изменении размера окна - PullRequest
4 голосов
/ 28 июля 2010

Кажется, что это такой тривиальный вопрос, но меня это некоторое время раздражало.

У меня есть окно, содержащее вид прокрутки.Как правило, представление прокрутки имеет DocumentView, который по вертикали больше, чем представление клипа, поэтому вы получаете вертикальную прокрутку для просмотра всего содержимого в представлении прокрутки.

Когда я изменяю размер окна, я пересчитываю размерсодержимое в представлении прокрутки documentView (потому что представление прокрутки может стать тоньше, что может потребовать увеличения DocumentView по высоте).Побочный эффект, однако, заключается в том, что при изменении размера окна DocumentView удерживает нижний видимый край на одном уровне с нижним краем представления клипа (то есть он гарантирует, что последняя строка текста всегда видна).Это странный эффект, поскольку обычно окна удерживают верхний видимый край представления документа на одном уровне с верхним краем представления клипа (то есть самая верхняя строка текста в представлении документа остается прикрепленной к верху).

Итак, моя первоначальная мысль для решения этой проблемы состояла в том, чтобы просто реализовать windowDidResize: или windowWillResize: toSize: уведомление, заметить разницу между высотой старой оконной рамки и новой высотой, а затем просто прокрутить представление прокрутки так многодля того, чтобы верхняя строка вида прокрутки была прикреплена к вершине.

Однако по некоторым причинам это, похоже, не работает.Это почти работает, но некоторые дельты изменения размера кажутся отключенными на пиксель, и если вы изменяете размер окна достаточно быстро, иногда это составляет ~ 10 пикселей.Таким образом, эффект состоит в том, что верхняя строка вида прокрутки почти прикреплена к вершине, но не совсем, и это отвлекает.

Есть ли лучший способ сделать это?Вот соответствующий код:

- (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)];

    [...]

}

Ответы [ 3 ]

10 голосов
/ 28 июля 2010

Ваш вид документа должен переопределить метод isFlipped - (BOOL) и вернуть YES.

1 голос
/ 08 января 2014

при повороте clipview не нужно изменять documentView после смены координат.

@interface FlippedClipView : NSClipView 
@end

@implementation FlippedClipView
- (BOOL)isFlipped
{
    return YES;
}
@end
0 голосов
/ 01 февраля 2019

Я обнаружил, что если я добавлю contentInsets в свой scrollView, настройка смещения в конце изменения размера будет отключена размером моего нижнего врезки. Очень расстраивает.

Я исправил это с помощью следующего пользовательского NSScrollView.

    var lastOffset = NSPoint.zero

    override func viewWillStartLiveResize() {
        lastOffset = documentVisibleRect.origin
    }

    override func viewDidEndLiveResize() {
        documentView?.scroll(lastOffset)
    }

Если у вас есть DocumentViews, которые изменяют размер при изменении scrollView, вам нужно будет выполнить вычисления смещения, когда вы установите их обратно. Вам нужно будет установить смещение после каждого вызова layout () между вызовами изменения размера в реальном времени, чтобы движение также было плавным.

...