Пользовательские проблемы NSScroller - PullRequest
2 голосов
/ 15 июля 2010

Я пытаюсь создать подкласс NSScroller, чтобы нарисовать собственную ручку скроллера.Для этого я использую подкласс NSScrollView и использую следующий код для создания своих пользовательских NSScrollers:

- (void)awakeFromNib;
{
    NSRect horizontalScrollerFrame = [[self horizontalScroller] frame];
    NSRect verticalScrollerFrame = [[self verticalScroller] frame];
    NSString *scrollBarVariant = [[[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain] valueForKey:@"AppleScrollBarVariant"];

    if (![scrollBarVariant isEqualToString:@"DoubleBoth"]) {
        [self setVerticalScroller:[[[TRScroller alloc] initWithFrame:verticalScrollerFrame] autorelease]];
        [self setHorizontalScroller:[[[TRScroller alloc] initWithFrame:horizontalScrollerFrame] autorelease]];
    }
}

Это работает, и мои NSScrollers отображаются правильно.Но я иногда вижу проблемы с рендерингом при первой загрузке приложения.В Интерфейсном Разработчике я выложил несколько NSScrollViews с их полосами прокрутки, настроенными на автоматическое скрытие.Проблема, с которой я сталкиваюсь, заключается в том, что при первой загрузке приложения фоны полосы прокрутки отображаются в содержимом NSScrollViews.

alt text http://www.freeimagehosting.net/uploads/1d3fc75db8.png

Я считаю, что это потому, что я создаю экземпляр своего NSScrollподкласс (TRSubclass) через awakeFromNib, что означает, что полосам прокрутки присваивается кадр NSScrollView, прежде чем он автоматически изменяется в соответствии с сохраненным местоположением и размером окон (другими словами, он использует кадр, назначенный по умолчанию в Интерфейсном Разработчике).Как лучше всего обойти это?

Я пытался заставить NSScrollView повторно отображать (используя setNeedsDisplay: и display :), но безуспешно.Кто-нибудь еще сталкивался с подобной проблемой?

1 Ответ

2 голосов
/ 15 июля 2010

Я использую ту же схему в своих приложениях, и я много боролся с этими проблемами. Я использую тот же трюк: скроллеры подставляются в [scrollView awakeFromNib] методах, но в настоящий момент я не сталкиваюсь с такими проблемами рендеринга Вы можете попробовать поиграть со свойством NSScrollView "рисует фон" - иногда это действительно помогает

- (void)changeSubs
{
    // change clip view
    // ...

    // change scrollers
    NSRect horizontalScrollerFrame = [[self horizontalScroller] frame];
    NSRect verticalScrollerFrame = [[self verticalScroller] frame];
    if (![[self verticalScroller] isKindOfClass:[CRScroller class]])
        [self setVerticalScroller:[[[CRScroller alloc] initWithFrame:verticalScrollerFrame] autorelease]];
    if (![[self horizontalScroller] isKindOfClass:[CRScroller class]])
        [self setHorizontalScroller:[[[CRScroller alloc] initWithFrame:horizontalScrollerFrame] autorelease]];
}

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
    [self changeSubs];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    NSKeyedUnarchiver* unpacker = (id)aDecoder;
    [unpacker setClass:[CRClipView class] forClassName:[NSClipView className]];
    [unpacker setClass:[CRScroller class] forClassName:[NSScroller className]];

    self = [super initWithCoder:aDecoder];
    if (self)
    {
    }
    return self;
}

- (void)awakeFromNib
{
    [self changeSubs];
}

Здесь есть несколько хитростей, они работают в зависимости от способа создания NSScrollView. Проверка isKindOfClass помогает избежать двойной замены.

...