我正在尝试子类化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内容呈现。
alt text http://www.freeimagehosting.net/uploads/1d3fc75db8.png
我相信这是因为我通过awakeFromNib实例化我的NSScroll子类(TRSubclass),这意味着在自动调整大小以满足窗口保存的位置和大小之前,滚动条被赋予NSScrollView的框架(换句话说,它是使用Interface Builder中默认分配的框架。最好的方法是什么?
我已经尝试强制NSScrollView重新显示(使用setNeedsDisplay:并显示:)但没有运气。还有其他人遇到过类似的问题吗?
答案 0 :(得分: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'检查有助于避免双重交换。