Macos -[NSButton setImage:]仅在第一次重新绘制时';这叫什么
我正在使用一个基于视图的Macos -[NSButton setImage:]仅在第一次重新绘制时';这叫什么,macos,cocoa,nsbutton,Macos,Cocoa,Nsbutton,我正在使用一个基于视图的NSTableView,它使用一个自定义单元格视图,其中包含多个控件。其中一个控件是仅显示图像的按钮,该按钮显示复选标记图像或根本不显示图像。此外,当我将鼠标移到其中一个没有图像的按钮上时,我希望在鼠标位于按钮内时显示选中标记图像的“褪色”版本 我已使用NSTrackingArea设置代码,以响应-mouseEntered:和-mouseExited:事件,在NSButton上调用-setImage:以在鼠标位于按钮内时显示褪色的复选标记,然后在鼠标退出时将图像设置回零
NSTableView
,它使用一个自定义单元格视图,其中包含多个控件。其中一个控件是仅显示图像的按钮,该按钮显示复选标记图像或根本不显示图像。此外,当我将鼠标移到其中一个没有图像的按钮上时,我希望在鼠标位于按钮内时显示选中标记图像的“褪色”版本
我已使用NSTrackingArea设置代码,以响应-mouseEntered:
和-mouseExited:
事件,在NSButton上调用-setImage:
以在鼠标位于按钮内时显示褪色的复选标记,然后在鼠标退出时将图像设置回零
据我所知,所有这些代码似乎都按预期工作,但当鼠标第一次进入视图时,按钮将更新并显示复选标记图像,然后在退出时消失,第二次将鼠标移回按钮上方不会导致按钮出于某种原因重新绘制,无论图像设置了多少次,在第一次重画后始终保持空白
这是相关代码的摘要:
- (void)refreshActiveButton
{
self.activeButton.image = self.activeImage;
}
- (void)mouseEntered:(NSEvent *)theEvent
{
NSLog(@"mouse entered %@", self.listItem.name);
self.mouseOverActiveButton = YES;
[self refreshActiveButton];
}
- (void)mouseExited:(NSEvent *)theEvent
{
NSLog(@"mouse exited %@", self.listItem.name);
self.mouseOverActiveButton = NO;
[self refreshActiveButton];
}
- (NSImage*)activeImage
{
NSLog(@"returning new active image");
if (self.listItem.isActive)
return [NSImage imageNamed:@"checkmark16"];
else if (self.mouseOverActiveButton)
return fadedCheckmark;
else
return nil;
}
该按钮在.xib文件中设置为“瞬时推入”(我也尝试过“瞬时更改”-相同的行为),没有显示标题和边框
在调试器中运行时,我能够确认:
- 当将鼠标移到按钮上时,即使显示不更新,也会继续调用
和-mouseenterned:
方法-mouseExited:
- 将正确的图像分配给按钮,并在设置后从按钮实例返回。(当鼠标位于内部时为淡入淡出复选标记图像,或当鼠标位于外部时为零)
-setNeedsDisplay:YES
,以及设置nsviewlayercontentsredawonsetneedsdisplay的layercontentrrawpolicy
(整个表视图是层备份的),但行为没有改变。编辑:还尝试完全禁用图层备份,没有任何更改
我觉得我的脸上一定有什么明显的东西在盯着我,但如果有人能给我提供线索,我将不胜感激。简短的回答:这是一个bug!我已经在苹果公司注册了雷达20774731,并在开放雷达上注册了
基本顺序是,如果您将按钮的图像设置为某个值,然后将其设置回nil,则所有后续的setImage:
调用都不会对按钮产生任何影响,据我所知,永远如此。我确实忘了在原来的帖子中提到这一切都在10.10.3上。不过,我在调试时确实发现了一些有趣的东西
似乎一旦您在NSButton
上设置了一个图像,在运行循环的另一个过程之后,它将获得一个NSImageView
作为子视图,该子视图可能正在实际绘制图像。苹果公司曾表示,他们正朝着弃用的方向发展,因此我想这是第一步,解除了实际绘制图像的责任
因此,第一次设置图像时,图像会在NSButton
和NSImageView
上正确设置。当图像被设置回零时,他们两人的图像也被设置回零。但是,当您再次设置图像时,虽然NSButton
自己的image
属性确实返回新图像,但基础NSImageView
的image
属性仍然为零。这也许可以解释为什么它什么都没画
最终我使用的是一个普通的NSImageView,上面有一个透明的NSButton
。当你点击一个按钮时,我没有得到你所得到的突出显示,但我可以接受。你试过记录从-activeImage返回的特定图像吗?也许图像正在设置,但没有达到您的预期?特别是,是否可能self.listItem.isActive状态未按预期更新?抱歉-我浏览了一下,没有注意到您确认设置了正确的图像。它看起来确实是完全相同的图像。在这种情况下,它要么是fadedCheckmark图像(当鼠标在里面时)要么是nil(当鼠标在外面时)。这是listItem.isActive为NO.OK的行的全部内容-下一个头脑风暴想法:这是否可能因为某种模式运行循环而不重新绘制?这一切都在一次拖动中,对吗?也许您需要使用一些模式来运行runloop,以鼓励它重新绘制?我只是在这里疯狂地进行头脑风暴,直到有知识渊博的人出现……头脑风暴很好!但是这里没有拖动,只需将鼠标“悬停”在按钮上。对于傻笑,我只是尝试了dispatch_async()-ing setImage:call,但没有骰子。也许我下一步会重置婴儿车。您是否考虑过将图像切换为全透明图像,而不是将其设置为nil
?