NSCell 重绘问题
-
11-12-2019 - |
题
我正在创建一个 NSCell
将一些对象直接绘制到视图上的子类(使用 drawInRect:fromRect:operation:fraction:respectFlipped:hints:
)并且还绘制了一个 NSButton
简单地使用 NSView 的实例 addSubview:
选择器。
虽然使用第一种方法绘制的对象都正确绘制,但我在绘制 NSButton
正确。问题是我的 NSButton
实例将绘制在正确的位置,但会多次绘制。
我在互联网上对此进行了一段时间的研究,有些人建议使用缓存,但我不确定这是否有效。(使用 for 循环访问包含按钮的数组肯定会导致滚动缓慢,因为我显示了大量数据......)
你会怎么做?我是不是找错了树?
这是相关代码:
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSRect _controlRect = cellFrame;
float _Y = cellFrame.origin.y;
NSRect _accessoryRect = NSMakeRect(_controlRect.size.width - 70.0f, _Y + 9.0f, 50.0f, 23.0f);
_switch = [self _choiceSwitch];
[_switch setFrame:_accessoryRect];
[controlView addSubview:_switch];
}
解决方案
长话短说: 朋友不让朋友 addSubview
, ,在绘图时。
这是一个基本的,并且 没有特别清楚地解释 管理控制接口的一个方面,但掌握起来很重要。
让您的控制器决定子视图的“顺序”,并且您可以高枕无忧,因为您知道该按钮不应该被公然弄乱(如果它在您的自定义绘图例程中被推来推去,则情况并非如此)。
很容易被困在这个巷子里 因为,就像,嘿,我添加了一个 NSImageView
在我的 initWithFrame
一切似乎都很好……但它是 只是有点不是你应该做的, ,我猜......当你开始子类化 NSControl 等时。就是当你开始意识到原因的时候。
更新: 这是一篇关于设计自定义控件的非常好的文章 与 同样出色的示例项目 附件 - 它体现了可以帮助避免此类问题的代码组织类型。例如..您会注意到在控制器类中他如何保持每个按钮独立、唯一且独立于其他视图的业务……
for (int butts = 0; butts < 3; butts++) {
NSRect buttFrame = NSMakeRect(0, butts * 10, 69, 10);
ExampleButt *butt = [[ExampleButt alloc]initWithFrame:buttFrame];
[mainView addSubview:butt];
}
其他提示
“绘画” NSButton
每次绘制单元格本身时将其实例添加到视图层次结构中绝对是一个坏主意。相反,创建一个 NSButtonCell 并根据您的喜好对其进行配置。然后,在你的 -[NSCell drawInteriorWithFrame:inView:]
使用单元格 ivar 绘制其外观。
如果你想要一个可点击的 NSButton
表视图的每个单元格中的实例,尽量避免调用 addSubview:
如果可能。每次执行此操作时,控制视图可能会使其布局无效并从头开始重新绘制所有内容,从而在您的情况下进行某种递归。