简体   繁体   English

NSTextView 重叠 NSButton 并使其不可点击

[英]NSTextView overlapping NSButton and making it unclickable

I'm creating a custom NSButton, and since I'm subviewing it with a gradient view, the default textView disappears.我正在创建一个自定义 NSButton,并且由于我使用渐变视图对其进行子查看,因此默认 textView 消失了。 In order to have also custom styling on the textView, I've created a custom one and subviewed that too.为了在 textView 上也有自定义样式,我创建了一个自定义样式并对其进行了子查看。

The button now looks like:该按钮现在看起来像:

在此处输入图片说明

Which is perfect.这是完美的。 But when I click on it, the NSButtonCell isn't triggering the highlight method (only if I click outside the textView (there's 5px spacing on bottom and top)但是当我点击它时,NSButtonCell 不会触发高亮方法(只有当我在 textView 之外点击时(底部和顶部有 5px 的间距)

How can I (just like in iOS's UIButton add a custom label) and still keeping the whole button clickable.我怎样才能(就像在 iOS 的 UIButton 中添加自定义标签一样)并且仍然保持整个按钮可点击。

Any help would be appreciated!任何帮助,将不胜感激!

Sjors斯约斯

So you want a click event on the NSTextView ? 因此,您要在NSTextView上单击事件吗?

Here is one solution. 这是一个解决方案。 Subclass the NSTextView 子类化NSTextView

@interface ClickableTextView : NSTextView
@end

@implementation ClickableTextView

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

@end

An NSTextField is a control and therefore captures input events. NSTextField是控件,因此捕获输入事件。 You shouldn't use it to display the text in a button. 您不应该使用它在按钮中显示文本。 NSButton uses NSCell for its drawing so it's best to subclass NSButtonCell and manually draw the string with NSStringDrawing, but only if you really can't use the standard layout properties of NSButtonCell. NSButton使用NSCell进行绘制,因此最好继承NSButtonCell的子类并使用NSStringDrawing手动绘制字符串,但前提是您确实不能使用NSButtonCell的标准布局属性。 This isn't iOS, where there is something like UILabel as a lightweight solution to draw text. 这不是iOS,而是UILabel之类的东西作为绘制文本的轻量级解决方案。 Instead, NSTextField provides a lot of overhead and would slow down your application and may provide you with unnecessary bugs, now or in the future. 相反,NSTextField提供了很多开销,并且会降低您的应用程序的速度,并且可能会为您提供不必要的错误(无论现在还是将来)。

Tl;dr: Don't use NSTextField, draw the string yourself. Tl; dr:不要使用NSTextField,自己绘制字符串。

NSButton uses an NSButtonCell to do all its drawing. NSButton使用NSButtonCell进行所有绘制。 The best solution that doesn't break Accessibility and doesn't have the label show up as a "Label" separate from the button to VoiceOver is to subclass NSButtonCell and to override its -drawBezelWithFrame:inView: method to draw your own button border there . 不破可及性和不具有标签显示为一个“标签”从按钮的VoiceOver独立的最好的解决办法是继承NSButtonCell并覆盖其-drawBezelWithFrame:inView:方法自己绘制按钮边框。

That said, if you wanted to make a view "transparent" for clicks, you could do so by overriding the -hitTest: method it inherits from NSView to return nil. 就是说,如果您想使点击的视图“透明”,则可以通过覆盖它从NSView继承的-hitTest:方法以返回nil来实现。 However then you'd also have to make sure you set it to be ignored by accessibility to avoid weirdness. 但是,您还必须确保将其设置为可访问性忽略,以免产生怪异。

Maybe, instead of using an NSView to draw text, a better approach would be to use a CALayer. 也许不是使用NSView绘制文本,而是一种更好的方法是使用CALayer。 Layers are more lightweight than views, and by default don't take part in hit testing. 图层比视图更轻便,默认情况下不参与命中测试。 There is even a text layer type that takes care of properly drawing. 甚至还有一个文本图层类型都可以正确绘制。 This is what Apple started using recently (in 10.8, or maybe it was already 10.7) for NSButtons if they use the standard configuration and don't override anything. 如果它们使用标准配置并且不覆盖任何内容,这就是Apple最近(在10.8中或也许已经在10.7中)开始使用的按钮。 They use one layer for the bezel (whose middle they stretch), and another for the text, IIRC. 他们在边框上使用一层(中间伸展),在文本上使用IIRC。 That way, only one texture needs to be uploaded to the GPU for all buttons of the same type. 这样,对于同一类型的所有按钮,只需将一个纹理上载到GPU。 Only if you override something in NSButton, Apple will fall back to a compatibility mode that actually uses NSCell. 仅当您在NSButton中重写某些内容时,Apple才会退回到实际使用NSCell的兼容模式。

You can use a NSStackView as the content view of NSTextView.您可以使用 NSStackView 作为 NSTextView 的内容视图。 In this case, the NSTextView part of the button is clickable.在这种情况下,按钮的 NSTextView 部分是可点击的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM