Cocoa 如何根据跟踪区域,使NSTableRowView TraffackGroundInRect在滚动上更新得足够快?
我将基于视图的NSTableView与自定义NSTableRowView一起使用。我想通过trackgroundinrect使用自定义行背景图,基于使用trackingaras的鼠标位置。目标是为鼠标当前悬停的未选定行绘制自定义背景 这实际上与从基于WWDC 2011会话视图的NSTableView Basic到Advanced完全相同。您可以在右侧account types表视图的Mail、Contacts&Calendars系统首选项窗格中看到该行为 与示例不同,我的表视图中有数千行。除非我快速滚动表格视图(例如,通过触摸板用两个手指轻弹),否则一切都与示例中的一样。在这种情况下,似乎updateTrackingAreas调用不够快。在鼠标下滚动的行将高亮显示,但从未通知鼠标离开其跟踪区域,因此保持高亮显示。结果是多行显示鼠标悬停高亮显示,并且由于重用队列,这些行将从表视图的一端滚动,然后在另一端重新显示(当然,数据不同),仍然高亮显示,就好像它们被鼠标悬停一样。缓慢滚动可以消除问题;但考虑到我希望滚动成千上万行,缓慢滚动并不是预期的用户行为Cocoa 如何根据跟踪区域,使NSTableRowView TraffackGroundInRect在滚动上更新得足够快?,cocoa,nstableview,Cocoa,Nstableview,我将基于视图的NSTableView与自定义NSTableRowView一起使用。我想通过trackgroundinrect使用自定义行背景图,基于使用trackingaras的鼠标位置。目标是为鼠标当前悬停的未选定行绘制自定义背景 这实际上与从基于WWDC 2011会话视图的NSTableView Basic到Advanced完全相同。您可以在右侧account types表视图的Mail、Contacts&Calendars系统首选项窗格中看到该行为 与示例不同,我的表视图中有数千行。除非我
我尝试了多种NSTrackingArea选项组合,但都没有效果,现在我被难倒了。任何关于解决这个问题的建议都将不胜感激。我认为这个问题的答案是“你不能”,即。,在快速滚动的
NSTableView
中,针对NSTableRowView
的updateTrackingAreas
在运行循环中发生的速度不够快,无法依赖它来确定指针是否在行视图中。同样,请参阅以查看正在使用updateTrackingAreas
的位置
不过,我确实认为我有一个合适的解决办法。我注意到twitterformac()有鼠标悬停的视图,这些视图随着鼠标移动而出现,但在滚动条上消失,这与我希望实现的鼠标悬停非常相似
为了执行此操作,我基本上让我的自定义NSTableRowView
有一个委托(我的自定义NSTableViewController
),它会询问该委托是否应该在悬停时高亮显示。我为我的NSTableView
使用了一个自定义的NSScrollView
,并调用了
[self.contentView setPostsBoundsChangedNotifications:YES];
在其awakeFromNib
中,并使其注册为该通知的观察者self
。在收到该通知(这意味着我的表视图正在滚动)时,我的自定义nscrollview
会将消息转发给我的NSTableViewController
当myNSTableViewController
接收到表视图正在滚动的消息时,它会禁用鼠标悬停时的高亮显示,如果之前的通知中还没有运行有效的计时器,则会在停止滚动后触发一个短计时器以重新启用鼠标悬停时的高亮显示。作为额外的预防措施,在鼠标悬停时启用和禁用高亮显示之间的状态转换时,myNSTableViewController
使用enumerateAvailableRowViewsUsingBlock
为每一行视图清除mouseInside
不确定这是否一定是最好的方法,但它达到了我想要的效果。此问题的解决方案如下所述: 我的updateTrackingAreas方法现在看起来像:
- (void)updateTrackingAreas {
if (trackingArea)
[self removeTrackingArea:trackingArea];
[trackingArea release];
trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
options:NSTrackingInVisibleRect |
NSTrackingActiveAlways |
NSTrackingMouseEnteredAndExited
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
NSPoint mouseLocation = [[self window] mouseLocationOutsideOfEventStream];
mouseLocation = [self convertPoint: mouseLocation fromView: nil];
if (NSPointInRect(mouseLocation, [self bounds]))
[self mouseEntered:nil];
else
[self mouseExited:nil];
[super updateTrackingAreas];
}
我没有想到鼠标指针没有进入/离开单元格,因为它实际上是静止的。这比我(显然不正确)所说的
updateTrackingAreas
调用速度不够快更有意义。如果我有机会回到这个问题上来,我会尝试这种方法。@JefferyRPrice这个方法适用于基于视图的表视图行吗?我已经实现了它,但我仍然有突出显示的相同行为,而不是在滚动上工作。有什么想法吗?@boyfarrell不幸的是,我无法尝试这个解决方案。我制作和使用的项目仍然使用我自己(更复杂)的答案。很抱歉,我不能提供更多帮助。@boyfarrell另外,我的原始解决方案确实应用于基于视图的表视图行。没关系,我刚刚提出了一个非常干净的解决方案,我很满意。我使行视图响应剪辑视图“我正在滚动”通知。然后,如果鼠标在行视图上,我会重新绘制它们。