objective-c - 为什么文本字段中闪烁的光标会导致调用 drawRect?

标签 objective-c cocoa macos appkit

我的程序中有以下 View 层次结构设置。

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 完全被不透明 View 遮挡,我认为这会阻止消息到 MyCustomView 中的 drawRect,但是当光标闪烁时,MyCustomView 仍然会发送带有完全位于不透明 View 后面的 NSRect 的 drawRect 消息。

我是否遗漏了一个关键概念,或者这是闪烁光标的怪癖?


最佳答案

根据 Josh Caswell 的推荐自行解决此问题。


我在 CocoaHeads session 上问过这个问题。我得到了查看 NSView 的 hitTest 的建议。所以在我的两个自定义 View 上,我覆盖了 NSView 的 hittest 函数,如下所示:

- (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 的 subview 。
MyOpaqueCustomView (OCV) 是 contentView 的 subview 。

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 的 subview 。
MyOpaqueCustomView (OCV) 是 MyCustomView 的 subview 。

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 的响应定义了哪些 View 将被重绘。

关于objective-c - 为什么文本字段中闪烁的光标会导致调用 drawRect?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5243190/

相关文章:

macos - 捆绑到 Cocoa 应用程序中的 Git 无法在 bundle 中找到帮助程序

image - 在xcode(cocoa应用程序)中插入图像

macos - 使用 super View 调整特定 View 的大小

macos - 通过双击文件将参数传递给JavaFx应用程序

cocoa - 在工具栏中动态调整 NSSegmentedControl 的宽度和位置

macos - 使用从alSourceUnqueueBuffers()获得的缓冲区ID时,alBufferData()设置AL_INVALID_OPERATION

ios - 一键隐藏多个按钮 Objective C

TableView 导航栏上的 IOS 按钮不起作用

objective-c - NSTextContainer 排除路径 setter 无法识别?

iphone - Objective-C 隐藏实例变量