我的程序中有以下视图层次结构设置。
Window
+ContentView (Subview of Window)
++MyCustomView (Subview of ContentView)
++MyCustomOpaqueView (Subview of ContentView)
+++TextField (Subview of MyCustomOpaqueView)
当用户单击TextField时,其中的光标开始闪烁。 在每次闪烁时,在MyCustomView上调用drawRect。没什么大不了的,但我想知道为什么?
在MyCustomOpaqueView中,我实现isOpaque,就像这样,
- (BOOL)isOpaque {return YES;}
我认为如果传递给drawRect的NSRect被一个不透明的视图完全遮挡,我会认为这会阻止消息传递给MyCustomView中的drawRect,但是当光标闪烁时,MyCustomView仍然会发送一个完全在不透明视图后面的NSRect的drawRect消息。
我是否错过了一个关键概念,或者这是闪烁光标的怪癖?
答案 0 :(得分:2)
根据Josh Caswell的推荐,自行解决这个问题。
我在CocoaHeads会议上询问了这个问题。我有一个建议来看看NSView的hitTest。所以在我的两个自定义视图中,我像这样覆盖了NSView的最热门功能:
- (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的子视图。
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的子视图。
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的响应定义了重绘的视图。