【问题标题】:Issue with setPatternPhase: in an NSSplitView for NSColor using colorWithPatternImage:setPatternPhase 的问题:在使用 colorWithPatternImage 的 NSColor 的 NSSplitView 中:
【发布时间】:2011-10-24 06:39:30
【问题描述】:

我已经四处搜索,但没有找到任何关于这个特定问题的信息。我有一个带有垂直 NSSplitView 的窗口。在 splitview 的右视图中,我设置了一个 NSBox 对象来填充视图的内容。我正在使用 setContentView 加载自定义笔尖:将视图交换到拆分视图右侧的 NSBox。在我的自定义视图中,我想用一个 NSColor 对象填充视图,该对象使用 NSImage 来图案化背景。所有这些都按预期工作。我正在使用基于这篇文章的代码:http://www.mere-mortal-software.com/blog/details.php?d=2007-01-08 将图案的相位设置为左上角:

[[NSGraphicsContext currentContext] saveGraphicsState];
[[NSGraphicsContext currentContext] setPatternPhase: NSMakePoint( [self bounds].origin.x, 
                                                                 [self bounds].size.height )];
[[self leatherColor] set];
NSRectFill( [self bounds] );

[[NSGraphicsContext currentContext] restoreGraphicsState];

当视图被重新调整大小时,模式在 NSBox 的左上角看起来保持不变,这将是预期的行为(通过拆分视图移动或窗口本身被调整大小)。我已经在一个精简的测试应用程序中实现了这一点,只有一个窗口和一个自定义视图,它的行为符合预期。

然而,在我的带有 splitview 的项目中,它的行为就像 patternPhase 被设置在整个窗口的左上角而不是 splitview 右半部分的左上角(即它应该随着调整大小而移动splitview)它的行为就像是“显示更大的图像而不是随之移动。我很确定这是多个坐标空间的问题,我误解了 NSSplitView 的坐标是如何工作的,或者与视图层次结构有关. 从关于 NSGraphicsContext 的文档中,在 setPatternPhase: 方法中它说:“例如,将模式阶段设置为 (2,3) 具有将模式单元平铺的开始移动到默认情况下的点 (2,3) 的效果用户空间。” 默认用户空间是否与我的自定义视图的边界相对应,或者可能是我基于右侧视图的坐标集创建点,而 setPatternPhase 将其实现为 spitview 的整个宽度(包括左半边)?

您可以提供的任何建议/建议/帮助将不胜感激。

编辑:我已经上传了项目的副本,因此您可以看到行为:http://dl.dropbox.com/u/6679821/ViewSwitcher.zip

【问题讨论】:

    标签: objective-c cocoa user-interface


    【解决方案1】:

    您需要根据视图在窗口中的位置调整相位。我在NSView上使用这个类别:

    @implementation NSView (RKAdditions)
    - (void)rk_drawPatternImage:(NSColor*)patternColor inRect:(NSRect)rect
    {
        [self rk_drawPatternImage:patternColor inBezierPath:[NSBezierPath bezierPathWithRect:rect]];
    }
    
    
    - (void)rk_drawPatternImage:(NSColor*)patternColor inBezierPath:(NSBezierPath*)path
    {
        [NSGraphicsContext saveGraphicsState];
    
        CGFloat yOffset = NSMaxY([self convertRect:self.bounds toView:nil]);
        CGFloat xOffset = NSMinX([self convertRect:self.bounds toView:nil]);
        [[NSGraphicsContext currentContext] setPatternPhase:NSMakePoint(xOffset, yOffset)];
    
        [patternColor set];
        [path fill];
        [NSGraphicsContext restoreGraphicsState];
    }
    
    @end
    

    在您的情况下,您可以将 -drawRect: 修改为如下所示:

    -(void) drawRect: (NSRect)dirtyRect
    {
        [self rk_drawPatternImage:[self leatherColor] inRect:self.bounds];
    }
    

    【讨论】:

    • 这非常有效。非常感谢您花时间发布您的出色答案。只是为了清楚起见,setPatternPhase 在窗口的坐标系上运行,而不是在调用它的视图上?
    猜你喜欢
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多