2

我正在尝试继承 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 显示正确。但是我偶尔会在第一次加载我的应用程序时看到渲染问题。在 Interface Builder 中,我布置了许多 NSScrollViews,它们的滚动条设置为自动隐藏。我看到的问题是,当应用程序首次加载时,滚动条背景会在 NSScrollViews 内容中呈现。

替代文字 http://www.freeimagehosting.net/uploads/1d3fc75db8.png

我相信这是因为我通过 awakeFromNib 实例化了我的 NSScroll 子类(TRSubclass),这意味着滚动条在自动调整大小以满足窗口保存的位置和大小之前被赋予了 NSScrollView 的框架(换句话说,它正在使用框架默认情况下在 Interface Builder 中分配)。解决这个问题的最佳方法是什么?

我试过强制 NSScrollView 重新显示(使用 setNeedsDisplay: 和 display:) 但没有运气。有没有其他人遇到过类似的问题?

4

1 回答 1

2

我在我的应用程序中使用相同的模式,并且我经常解决这个问题。我使用相同的技巧:在方法中替换了滚动条[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”检查有助于避免双重交换。

于 2010-07-15T14:24:21.397 回答