绘制聚焦环后,子类NSView的子视图重新定位不正确

时间:2013-06-21 12:05:24

标签: macos nsview autolayout nsimageview

我想在子类NSView之外创建一个聚焦环来识别选择。我的参考资料来自:Link

我按照引用,将-drawRect方法覆盖为:

@property (nonatomic) BOOL shouldDisplayFocus;
...

- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
if (_shouldDisplayFocus)
{
    [self setKeyboardFocusRingNeedsDisplayInRect:[self bounds]];
}

[super drawRect:dirtyRect];
[[NSColor blackColor] set];
NSRectFill(dirtyRect);

if (_shouldDisplayFocus)
{
    NSSetFocusRingStyle(NSFocusRingTypeExterior);
    NSBezierPath *path = [NSBezierPath bezierPathWithRect:NSInsetRect([self bounds], -1.0, -1.0)];
    [[NSColor blackColor] set];
    [path stroke];

    [NSGraphicsContext restoreGraphicsState];
}
}

它的-mouseDown:方法也被覆盖了:

- (void)mouseDown:(NSEvent *)theEvent
{
[super mouseDown:theEvent];
if (_delegate && [_delegate respondsToSelector:@selector(mouseDownAtView:withEvent:)])
{
    [_delegate mouseDownAtView:self withEvent:theEvent];
}
}

单击视图后,其委托将设置/取消设置焦点环,并使其再次调用-drawRect:




它正确地在视图外工作并生成了聚焦环。但是,很快就出现了一个问题:

http://oi39.tinypic.com/2s846jo.jpg

我在子视图中有一个图像视图。由于图像视图矩形是使用NSLayoutConstraint对象自动布局的,因此我创建了四个NSLayoutConstraint出口来调整它们的值。我不经常更改布局约束。实际上,由于图像尺寸保持不变,我不会设置它们。

以下是没有点击子类视图的情况(看起来很好):

http://oi42.tinypic.com/2urqcmf.jpg

然后点击图像(生成聚焦环,但......):

http://oi40.tinypic.com/33ldtfa.jpg

我试着调整窗口大小,事情变得更加悲伤“FUNNY”:

http://oi43.tinypic.com/25pshub.jpg

我无法理解问题的原因或解决方法。有人可以帮我吗?我在此处上传了示例代码:Download


很遗憾没有人回答这个问题。

我注意到,当通过-addSubview:-setFrame方法将子视图添加到此视图时,子视图的布局也不正确。

1 个答案:

答案 0 :(得分:1)

答案很晚,但无论如何它是:你在[NSGraphicsContext saveGraphicsState]区块的开头没有打电话给if (_shouldDisplayFocus) {

您调用[NSGraphicsContext restoreGraphicsState]将图形状态从堆栈中弹出,但您从未在堆栈中放置任何内容。 Cocoa正在使用图形状态堆栈绘制所有内容,因此您会弹出一些与图像位置有关的未知状态。如果要添加聚焦环样式并且能够移除聚焦环样式,则需要先保存图形状态,将聚焦环样式设置为您想要的任何颜色,然后将图形状态恢复为原样。 / p>