问题描述
我的程序中具有以下视图层次结构设置.
I have the following view hierarchy setup in my program.
Window
+ContentView (Subview of Window)
++MyCustomView (Subview of ContentView)
++MyCustomOpaqueView (Subview of ContentView)
+++TextField (Subview of MyCustomOpaqueView)
当用户单击TextField时,其内部的光标开始闪烁.每次闪烁时,都会在MyCustomView上调用drawRect.没什么大不了,但是我想知道为什么吗?
When the user clicks the TextField the cursor inside of it starts to blink.On each blink drawRect is called on MyCustomView. Not a big deal, but I'm wondering why?
在MyCustomOpaqueView中,我像这样实现isOpaque,
In MyCustomOpaqueView I implement isOpaque like so,
- (BOOL)isOpaque {return YES;}
我认为,如果传递给drawRect的NSRect完全被不透明的视图所遮盖,那么这将阻止消息传递给MyCustomView中的drawRect,但是当光标闪烁时,MyCustomView仍会发送带有NSRect的drawRect消息,而该消息完全位于不透明的视图后面.
I thought this would block messages to drawRect in MyCustomView if the NSRect passed to drawRect is entirely obscured by an opaque view, but when the cursor blinks MyCustomView still gets sent the drawRect message with an NSRect entirely behind an opaque view.
我是否缺少关键概念,或者这是闪烁的光标的怪癖?
Am I missing a key concept or is this a quirk of the blinking cursor?
推荐答案
在乔什·卡斯韦尔(Josh Caswell)的推荐下,自行解决此问题.
Self-Resolving this answering, on recommendation by Josh Caswell.
我在CocoaHeads会议上问了这个问题.我建议看一下NSView的hitTest.因此,在我的两个自定义视图上,我都像这样覆盖了NSView的hittest函数:
I asked about this at a CocoaHeads meeting. I got a suggestion to look at the NSView's hitTest. So on both my custom views, I overrode the NSView's hittest function like so:
- (NSView*) hitTest:(NSPoint)aPoint {
static int depth = 1;
NSLog([NSString stringWithFormat:@"%%%dd ENTER %%@ - hitTest", depth],
depth, [[self class] description]);
depth++;
NSView *hitView = [super hitTest:aPoint];
depth--;
NSLog([NSString stringWithFormat:@"%%%dd EXIT %%@ - hitTest: %%@", depth],
depth, [[self class] description], [[hitView class] description]);
return hitView;
}
下面是输出:
MyCustomView是contentView的子视图.
MyOpaqueCustomView(OCV)是contentView的子视图.
MyCustomView is subview of contentView.
MyOpaqueCustomView (OCV) is subview of contentView.
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextField
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextField
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextView
MyCustomView - Dirty Rect: {{49, 189}, {127, 28} //!!Focus Ring Around Text Field
OCV - Dirty Rect: : {{49, 189}, {127, 28}}
testTextField isOpaque? Yes
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextView
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}}
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextView
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextField
1 ENTER MyCustomView - hitTest
1 EXIT MyCustomView - hitTest: MyCustomView
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}} //!!EVERY BLINK
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}}
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}}
MyCustomView - Dirty Rect: {{64, 194}, {1, 17}}
MyCustomView是contentView的子视图.
MyOpaqueCustomView(OCV)是MyCustomView的子视图.
MyCustomView is subview of the contentView.
MyOpaqueCustomView (OCV) is subview of MyCustomView.
1 ENTER MyCustomView - hitTest
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextField
1 EXIT MyCustomView - hitTest: NSTextField
1 ENTER MyCustomView - hitTest
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextField
1 EXIT MyCustomView - hitTest: NSTextField
1 ENTER MyCustomView - hitTest
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextView
1 EXIT MyCustomView - hitTest: NSTextView
OCV - Dirty Rect: : {{49, 189}, {127, 28}} //!!FOCUS RING
testTextField isOpaque? Yes
1 ENTER MyCustomView - hitTest
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextView
1 EXIT MyCustomView - hitTest: NSTextView
1 ENTER MyCustomView - hitTest
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextView
1 EXIT MyCustomView - hitTest: NSTextView
1 ENTER MyCustomView - hitTest
1 ENTER OCV - hitTest
1 EXIT OCV - hitTest: NSTextField
1 EXIT MyCustomView - hitTest: NSTextField
//!!BLINKING HERE - But no dirtyRects.
因此,对hitTest的响应似乎定义了将重绘哪些视图.
So it looks like the response to hitTest defines what views will get redrawn.
这篇关于为什么文本字段中闪烁的光标会导致调用drawRect?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!