使用 scaleUnitSquareToSize 时在 NSTextView 中绘制焦点环:

Posted

技术标签:

【中文标题】使用 scaleUnitSquareToSize 时在 NSTextView 中绘制焦点环:【英文标题】:Drawing focus ring in NSTextView when using scaleUnitSquareToSize: 【发布时间】:2014-11-18 15:18:17 【问题描述】:

从 OSX 10.7 开始,Apple 建议使用 drawFocusRingMaskfocusRingMaskBounds 方法作为围绕基于 NSView 的对象绘制焦点环的方式,而不是之前在 10.6 中的方式(在 drawRect: 中使用 NSSetFocusRingStyle()) . (见release notes)。

在 OSX 10.10 上测试

我有一个 NSTextView 后代,它按照建议实现了基本的焦点环绘制:

- (void)drawFocusRingMask 
  NSRectFill([self bounds]);

- (NSRect)focusRingMaskBounds 
  return [self bounds];
 

这个 NSTextView 以编程方式直接添加到内容视图中(没有任何滚动视图)。

这在大多数情况下效果很好,但是,当使用scaleUnitSquareToSize: 缩放 NSTextView 时,绘制的焦点环完全不正确。

呼唤:

[textView scaleUnitSquareToSize:NSMakeSize(1.5, 1.5)];

看起来像这样:

进一步向上或向下缩放会导致对焦环矩形更加偏斜。将 NSTextView 的比例重置回 1.0, 1.0 会导致焦点环再次正确绘制。

我认为这是对焦环代码中的某种错误。在调用drawFocusRingMask/focusRingMaskBounds(内部类_NSAutomaticFocusRing负责此)之前,它似乎对用于绘制焦点环的图形上下文进行了转换。

知道如何解决这个问题吗?我是否应该找到一种方法将上下文转换为正确的坐标(到目前为止没有成功)?或者有没有其他方法可以强制对焦环正常工作?

【问题讨论】:

是否与从坐标系原点进行缩放有关? 视图的缩放不会直接影响对焦环,因为它是由 _NSAutomaticFocusRing 在不同的图形上下文中单独绘制的。 _NSAutomaticFocusRing 确实会查询视图并根据视图的坐标执行转换,我认为问题就在那里。 【参考方案1】:

重写 drawFocusRingMask 方法(通过 NSTextField 的子类)允许通过“手动”应用超级视图的比例因子来校正焦点环的宽度,但更改高度不起作用。我的猜测是焦点环的高度在缩放之前被固定到文本大小或原始文本字段边界。

这一切都在系统 10.7.5 上。所以我只是在文本字段的超级视图处于缩放状态时关闭焦点环,直到我能找到解决方法或任何正确的做法。

【讨论】:

【参考方案2】:

我已经为这个错误苦苦挣扎了很长时间。这是一个似乎可行的解决方案:

子类 NSTextFieldNSTextView 以便您实例化,例如 ZoomableTextField。覆盖它的drawFocusRingMask: 方法,这样覆盖什么都不做:

- (void)drawFocusRingMask


然后在嵌入了ZoomableTextField的可缩放superview中,在superview的drawRect:方法内,调用ZoomableTextField的新方法drawPossibleFocus,如下所示:

- (void)drawPossibleFocus

    NSWindow *win = [self window];
    if ([self currentEditor]==[win firstResponder] && [win isKeyWindow]) 
        [NSGraphicsContext saveGraphicsState];
        NSSetFocusRingStyle(NSFocusRingOnly);
        NSRectFill([self frame]);
        [NSGraphicsContext restoreGraphicsState];
        

【讨论】:

以上是关于使用 scaleUnitSquareToSize 时在 NSTextView 中绘制焦点环:的主要内容,如果未能解决你的问题,请参考以下文章

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份