简体   繁体   English

NSCell重绘问题

[英]NSCell redrawing issues

I'm creating a NSCell subclass that draws some objects directly onto the view (using drawInRect:fromRect:operation:fraction:respectFlipped:hints: ) and also draws an NSButton instance simply using NSView's addSubview: selector. 我正在创建一个NSCell子类,该子类将一些对象直接绘制到视图上(使用drawInRect:fromRect:operation:fraction:respectFlipped:hints: ,还可以使用NSView的addSubview:选择器简单地绘制NSButton实例。

While objects drawn using the first method all draw correclty, I'm having problems with drawing the NSButton correctly. 虽然使用第一种方法绘制的对象都具有正确性,但是我在正确绘制NSButton遇到问题。 The issue is that my NSButton instances will draw in the right places, but multiple times over. 问题是我的NSButton实例将在正确的位置绘制,但是绘制了多次。

I've researched this on the internet for a while and some people suggested using a cache, but I'm not sure if this is efficient. 我已经在互联网上研究了一段时间,有些人建议使用缓存,但是我不确定这是否有效。 (going an array containing buttons using a for loop will definately cause slow scrolling since I display a lot of data...) (因为包含大量数据,所以使用for循环访问包含按钮的数组肯定会导致缓慢的滚动...)

How would you do this? 你会怎么做? Am I barking up the wrong tree? 我在树上叫错了吗?

This is the relevant code: 这是相关代码:

- (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];
}

Long story short : Friends don't let friends addSubview , while drawing. 长话短说绘制时,朋友不要让朋友addSubview

This a fundamental, and not particularly well-explained aspect of managing control interfaces, but is important to come to grips with. 这是管理控制界面的一个基本的但不是特别解释的方面,但是必须牢记。

Let your controllers dictate the "order" of subviews, and you can sleep tight knowing that that button shouldn't get overtly mucked about (which is NOT the case if it's getting jostled around inside your custom drawing routines). 让您的控制器决定子视图的“顺序”,您就可以睡一觉,知道该按钮不应该被公然嘲笑(如果在您的自定义绘图例程中被挤作一团,情况并非如此)。

It's easy to get trapped in this alley, cause, like, hey, I added an NSImageView in my initWithFrame and everything seems to be okay … But it's just sort of not how you're supposed to do it , I guess… and when you start subclassing NSControl, etc. is when you start to realize why. 很容易陷入这个小巷, 原因是,嘿,我在initWithFrame添加了一个NSImageView ,一切似乎都还不错 ……但是,这大概不是您应该怎么做的 ,我想……当您开始子类化NSControl等,是当您开始意识到原因的时候。

Updated: Here's a really good write up on designing custom controls with an equally as great sample project attached - which embodies the kind of code organization that can help avoid this type of issue. 更新: 这是关于设计自定义控件的非常好的文章 ,其中附加了同样出色的示例项目 -体现了可以帮助避免此类问题的代码组织类型。 For example.. you'll notice in the controller class how he's keeping each button seperate, unique, and independent of other views' business… 例如,您将在控制器类中注意到他如何使每个按钮保持独立,唯一且独立于其他视图的业务……

for (int butts = 0; butts < 3; butts++) {
    NSRect buttFrame = NSMakeRect(0, butts * 10, 69, 10);
    ExampleButt *butt = [[ExampleButt alloc]initWithFrame:buttFrame];
    [mainView addSubview:butt];
}

在此输入图像描述

“Drawing” NSButton by adding its instance into the view hierarchy each time you draw the cell itself is definitely a bad idea. 每次绘制单元格本身时,通过将其实例添加到视图层次结构中来“绘制” NSButton绝对不是一个好主意。 Instead, create an NSButtonCell and configure it up to your taste. 而是创建一个NSButtonCell并根据您的喜好进行配置。 Then, in your -[NSCell drawInteriorWithFrame:inView:] use a cell ivar to draw its appearance. 然后,在-[NSCell drawInteriorWithFrame:inView:]使用单元格ivar绘制其外观。

If you want to have a clickable NSButton instance in each cell of the table view, try to avoid a call to addSubview: when possible. 如果希望在表视图的每个单元格中都有一个可单击的NSButton实例,请尽量避免调用addSubview: Each time you do this, the control view may invalidate its layout and re-draw everything from scratch making some kind of a recursion in your case. 每次您执行此操作时,控件视图都可能使其布局无效,并从头开始重新绘制所有内容,从而在您的情况下进行某种递归。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM