5

プログラムに次のビュー階層を設定しています。

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メッセージが送信されます。

私は重要な概念を見逃していますか、それともこれは点滅するカーソルの癖ですか?


4

1 に答える 1

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への応答は、どのビューが再描画されるかを定義しているように見えます。

于 2011-03-18T17:06:31.840 に答える