【发布时间】:2012-08-05 15:27:30
【问题描述】:
在我的项目中,有一个带有 NSButton 和 NSView 的窗口(它是其他视图的容器)。单击按钮将更改容器的子视图,如下所示:
[containerView replaceSubview:displayedSubview with:nextView];
添加到 containerView 的第一个子视图有一个 基于视图的 TableView(使用绑定)填充有 NSTableCellView 子类的对象。
这个子类 NSTableCellView 有一个跟踪区域,可以让我在鼠标进入/离开单元格时显示/隐藏按钮。
方法 mouseEntered: 和 mouseExited: 分别使用 setAlphaValue: 方法显示和隐藏 _buttonInsideTableCellView。
在init方法中创建跟踪区域如下:
NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited|NSTrackingActiveInActiveApp;
_trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:options owner:self userInfo:nil];
updateTrackingAreas 方法很简单:
- (void)updateTrackingAreas
{
[_buttonInsideTableCellView setAlphaValue:0.0];
[self removeTrackingArea:_trackingArea];
NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited|NSTrackingActiveInActiveApp;
_trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:options owner:self userInfo:nil];
[self addTrackingArea:_trackingArea];
[super updateTrackingAreas];
}
问题
当程序启动时,一切都按预期工作:如果鼠标悬停在单元格上,则显示其按钮。
但是在我将containerView的子视图更改为nextView并返回到第一个视图后,当子视图被替换时,方法updateTrackingAreas开始被多次调用(2次或更多),当应用程序变为活动时(???),当鼠标进入或离开trackingArea时(???)。
调用栈
如果我在 updateTrackingAreas 中放置断点,这里是调用堆栈:
#0 0x0000000100019e33 in -[CustomTableCellView updateTrackingAreas]
#1 0x00007fff8a1b24e4 in -[NSView(NSInternal) _updateTrackingAreas] ()
#2 0x00007fff894740b6 in __NSArrayEnumerate ()
#3 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#4 0x00007fff894740b6 in __NSArrayEnumerate ()
#5 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#6 0x00007fff894740b6 in __NSArrayEnumerate ()
#7 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#8 0x00007fff894740b6 in __NSArrayEnumerate ()
#9 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#10 0x00007fff8a1b36bd in -[NSScrollView _updateTrackingAreas] ()
#11 0x00007fff894740b6 in __NSArrayEnumerate ()
#12 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#13 0x00007fff894740b6 in __NSArrayEnumerate ()
#14 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#15 0x00007fff894740b6 in __NSArrayEnumerate ()
#16 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#17 0x00007fff894740b6 in __NSArrayEnumerate ()
#18 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#19 0x00007fff894740b6 in __NSArrayEnumerate ()
#20 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#21 0x00007fff894740b6 in __NSArrayEnumerate ()
#22 0x00007fff8a1b2960 in -[NSView(NSInternal) _updateTrackingAreas] ()
#23 0x00007fff8a1b237c in _handleInvalidCursorRectsNote ()
#24 0x00007fff8a6ac851 in __35-[NSWindow _postInvalidCursorRects]_block_invoke_02794 ()
#25 0x00007fff894420c7 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#26 0x00007fff89442031 in __CFRunLoopDoObservers ()
#27 0x00007fff8941d4a8 in __CFRunLoopRun ()
#28 0x00007fff8941cdd2 in CFRunLoopRunSpecific ()
#29 0x00007fff89a72774 in RunCurrentEventLoopInMode ()
#30 0x00007fff89a72454 in ReceiveNextEventCommon ()
#31 0x00007fff89a723a3 in BlockUntilNextEventMatchingListInMode ()
#32 0x00007fff8a0d7fa3 in _DPSNextEvent ()
#33 0x00007fff8a0d7862 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#34 0x00007fff8a0cec03 in -[NSApplication run] ()
#35 0x00007fff8a073656 in NSApplicationMain ()
#36 0x00000001000013a2 in main
#37 0x0000000100001374 in start ()
【问题讨论】:
-
为什么要使用 updateTrackingAreas?如果您不更改表格单元格视图的边界,我认为您不需要这样做。
-
TableView(及其单元格)随窗口调整大小。
-
我不确定您看到的内容有什么问题。由于您帖子中的所有问号,很难准确判断何时调用更新,但我认为每当您的视图出现(表中的每个可见行一次)以及滚动或调整大小时都应该调用它。
-
有问号是因为在那些情况下调用该方法很奇怪。
-
当视图关闭/打开屏幕时调用它......听起来很合理
标签: cocoa