NSView - 绘制双色检查器

时间:2015-09-12 13:19:21

标签: objective-c cocoa nsview

我有一个NSView的子类,我需要绘制双色检查器(交替颜色的方块)。以下是我所拥有的。

- (void)drawRect:(NSRect)rect {    
    NSInteger k = 1;
    for (int j = 0;  j < self.frame.size.width; j += 20) {
        for (int i = 0; i < self.frame.size.height; i +=20) {
            if (k%2 == 0) {
                [[NSColor whiteColor] set];
            }
            else {
                [[NSColor lightGrayColor] set];
            }
            [NSBezierPath fillRect:NSMakeRect(j,i,20,20)];
            k++;
        }
    }
}

如果我运行它,我会得到交替颜色的正方形。如果我改变框架高度,我有时会得到交替颜色的条纹。如何改进上面的代码?

感谢。

4 个答案:

答案 0 :(得分:1)

绘制棋盘图案的另一种方法是在绘图程序中制作2x2棋盘,将其作为资源添加到项目中,将该图像传递给+[NSColor colorWithPatternImage:],然后您只需填写一个区域即可那种颜色。

答案 1 :(得分:1)

好的,问题是一行中可能有一个奇数个方块,在这种情况下,下一行再次显示相同的模式。这是我如何解决它;我还将NSBezierPath的使用改为NSRectFill(),因为后者在概念上更简单,而且可能更快。

- (void)drawRect:(NSRect)rect {    
    for (int j = 0;  j * 20 < self.frame.size.width; j++) {
        for (int i = 0; i * 20 < self.frame.size.height; i++) {
            if (((i^j) & 1) == 0)
                [[NSColor whiteColor] set];
            else
                [[NSColor lightGrayColor] set];
            NSRectFill(NSMakeRect(j*20,i*20,20,20));
        }
    }
}

(i^j) & 1使用按位异或 - (^运算符)然后按位和(&amp;运算符)组合行和列索引的奇偶状态。有多种方法可以优化乘法,但这段代码似乎是最清晰的方法。 一个更清洁的版本,运行速度更快,可能会避免一些绘图工件,将涉及首先清除一种颜色,然后只绘制相反颜色的正方形:

- (void)drawRect:(NSRect)rect {
    [[NSColor whiteColor] set];
    NSRectFill(rect);
    [[NSColor lightGrayColor] set];
    for (int j = 0;  j * 20 < self.frame.size.width; j++)
        for (int i = 0; i * 20 < self.frame.size.height; i++)
            if ((i^j) & 1)
                NSRectFill(NSMakeRect(j*20,i*20,20,20));
}

答案 2 :(得分:0)

请记住,您的视图不会因为调整大小而重新绘制!所以你的棋盘会被视图挤压或拉伸。您可以致电setNeedsDisplay

答案 3 :(得分:0)

您确定方形颜色的方法会将颜色沿列向下交替,然后继续下一列。如果你有一个偶数行,每行将以相同的颜色开始,给你条纹。

简单地说,你只需要两个状态 - 黑色或白色 - 所以不是整数,加法和奇数/偶数测试来将整数减少到两个值中的一个,只是从只有两个值的类型开始,即布尔值

要处理奇数或偶数行的问题,请使用两个变量,一个用于跟踪列中第一个方块的颜色 - 这将覆盖外循环的每次迭代,并且一个跟踪颜色当前的平方 - 对于每一列,它以第一个变量的值开始,并翻转内部循环的每次迭代。

在代码大纲中,在外循环之前:

BOOL colStartsWhite = YES; // or NO, you decide - this is the corner color

在外环内:

BOOL squareIsWhite = colStartsWhite; // inner tracker
colStartsWhite = !colStartsWhite; // flip ready for next column

内循环内部:

if (squareIsWhite) ... else ... // fill the square
squareIsWhite = !squareIsWhite; // flip for next square

HTH