我有一个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++;
}
}
}
如果我运行它,我会得到交替颜色的正方形。如果我改变框架高度,我有时会得到交替颜色的条纹。如何改进上面的代码?
感谢。
答案 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