NSTextView重叠NSButton并使其无法点击

时间:2014-03-11 10:37:02

标签: objective-c macos cocoa nsbutton

我正在创建一个自定义NSButton,因为我使用渐变视图对其进行子视图,所以默认的textView会消失。为了在textView上也有自定义样式,我创建了一个自定义样式并且也查看了它。

按钮现在看起来像:

enter image description here

哪个是完美的。 但是当我点击它时,NSButtonCell没有触发高亮方法(只有当我在textView外面点击(底部和顶部有5px的间距)

我怎么能(就像在iOS的UIButton中添加自定义标签一样)并且仍然可以保持整个按钮可点击。

任何帮助将不胜感激!

Sjors

3 个答案:

答案 0 :(得分:1)

所以你想要NSTextView上的点击事件?

这是一个解决方案。对NSTextView

进行子类化
@interface ClickableTextView : NSTextView
@end

@implementation ClickableTextView

- (void)mouseDown:(NSEvent *)theEvent{
    [self sendAction://action of the button that you want
                  to:self
    ];
}

@end

答案 1 :(得分:1)

NSTextField是一个控件,因此捕获输入事件。您不应该使用它来显示按钮中的文本。 NSButton使用NSCell进行绘制,因此最好将NSButtonCell子类化并使用NSStringDrawing手动绘制字符串,但前提是您实际上不能使用NSButtonCell的标准布局属性。这不是iOS,其中有像UILabel这样的轻量级解决方案来绘制文本。相反,NSTextField会提供大量开销,并会降低您的应用程序速度,并且可能会在现在或将来为您提供不必要的错误。

Tl; dr:不要使用NSTextField,自己绘制字符串。

答案 2 :(得分:1)

NSButton使用NSButtonCell来完成所有绘图。没有破坏可访问性且没有标签的最佳解决方案显示为"标签"从按钮分离到VoiceOver是子类NSButtonCell并覆盖其-drawBezelWithFrame:inView:方法来绘制自己的按钮边框那里

那就是说,如果你想提出一个观点,那么透明"对于点击,您可以通过覆盖从NSView继承的-hitTest:方法来返回nil。但是,您还必须确保将其设置为可访问性忽略,以避免出现怪异。

也许,不使用NSView绘制文本,更好的方法是使用CALayer。图层比视图更轻量级,默认情况下不参与命中测试。甚至还有一个文本图层类型,负责正确绘图。这是Apple最近开始使用的(在10.8中,或者可能已经是10.7),如果他们使用标准配置并且不覆盖任何东西,则可以使用NSButton。他们使用一层用于挡板(它们的中间部分伸展),另一层用于文本IIRC。这样,对于相同类型的所有按钮,只需要将一个纹理上载到GPU。只有在NSButton中覆盖某些内容时,Apple才会回退到实际使用NSCell的兼容模式。