如何在Cocoa中绘制正方形网格?

时间:2012-11-10 03:46:53

标签: objective-c cocoa

我正在为Cocoa开发一个视觉Conway's Game of Life程序。当然,主视图基本上是方形图块网格,随着算法的进展在黑色和白色之间改变颜色,但是我很难找出绘制和管理这个正方形网格的最佳方法。

我最初的想法是让每个磁贴都是NSView的子类。绘图非常简单:如果它还活着就填充黑色,如果它已经死了则填充为白色。但我不知道如何把它放在窗户里;将它作为单独的NSView(并为每个NSView设置IB出口)在Interface Builder中进行布局似乎很乏味。我可以通过编程方式定位它们,但这看起来也很乏味(特别是因为我希望每个磁贴之间有一点空间)。

我记得NSMatrix明确地设计用于接口对象的数组(或网格),所以我想我可以创建NSView子类的NSMatrix。问题是,似乎你只能创建NSControls的NSMatrix。我的自定义磁贴视图本身并不是一个控件,因为它不需要接受鼠标跟踪事件等,但我想我可以伪造它并仅用于绘图(和只是忽略任何事件。)

当然,如果您使用的是一大堆相同类型的NSControl,最好使用NSCell进行绘图,但NSCell似乎更适合绘制基于文本或图像的控件;我没有看到简单的方法来绘制黑色或白色。

我倾向于滥用NSControl子类进行绘图,并跳过将NSCell与之关联起来,但我想知道是否有更好的方法或者我还没有想到的东西。

4 个答案:

答案 0 :(得分:0)

我是通过使用自定义buttonCells矩阵在之前的项目中完成此操作的。我在按钮单元格中添加了backgroundColor属性,因此我可以在没有边框的单元格上获得彩色背景(标准单元格类型无法实现)。这是我做的NSButtonCell的子类:

@interface RDButtonCell : NSButtonCell <NSCoding> 

@property (retain) NSColor *selectedColor;
@property (retain) NSColor *backgroundColor;

-(id)initWithRGBAlpha:(NSArray *)rgbAlpha;


@implementation RDButtonCell

-(id)initWithRGBAlpha:(NSArray *)rgbAlpha {
    if (self = [super init]) {
    NSColor *color = [NSColor colorWithCalibratedRed:[rgbAlpha[0]doubleValue]
                                               green:[rgbAlpha[1]doubleValue] 
                                                blue:[rgbAlpha[2]doubleValue] 
                                               alpha:[rgbAlpha[3]doubleValue]];
    [self setBackgroundColor:color];
    [self setTitle:@""];
    [self setBordered:NO];
    [self setTag:0];
    }
    return self;
}

-(void) setState:(NSInteger)value {
    if (value == 1) {
        self.backgroundColor = self.selectedColor;
        [super setState:value];
    }else {
        self.backgroundColor = self.backgroundColor;
        [super setState:value];
    }
}


-(void) setBackgroundColor:(NSColor *)color {
    _backgroundColor = color;
    _selectedColor = [color colorWithAlphaComponent:.75];
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    [super encodeWithCoder:encoder];
    [encoder encodeObject:_backgroundColor forKey:@"bColor"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super initWithCoder:decoder];
    _backgroundColor = [decoder decodeObjectForKey:@"bColor"];
    return self;
}

答案 1 :(得分:0)

一种方法是在视图中托管CALayer并为每个单元格创建一个CALayer(每个单元格图层都是视图图层的子图层)。然后只需设置图层的背景颜色。

答案 2 :(得分:0)

“最佳”可能会有所不同,具体取决于您所写的内容以及您所呈现的矩阵的大小。当然,NSMatrix在可能的情况下可以正常工作,但是使用它并且许多单元格会降低可以完成的上限。对于大矩阵或高更新频率,您可以考虑避免使用更高级别的抽象。

NSMatrix的替代方案:在这种情况下,矩阵逻辑非常简单。如有必要,将它或工作分开也很容易。实现该逻辑后,您可以:

  • 使用CGContextFillRect(或NSRectFill
  • 或使用位图(例如使用CGBitmapContext生成图像)

答案 3 :(得分:0)

我把这个简单的统一网格类放在一起。它是基于行的,并且如果需要,每行支持不同数量的视图。为每行添加相同数量的子视图会生成一个真正的统一网格。

https://github.com/ThesaurusSoftware/TSUniformGrid