以下是我在我的应用程序中绘制棋盘的方法。除了使用静态图像之外,还有更有效或更明智的方法吗?
- (void)drawRect:(CGRect)rect {
int verticalOffset = 40;
int horizontalOffset = 0;
int squareSize = 40;
NSString *nextSquareColour = @"light";
CGContextRef context = UIGraphicsGetCurrentContext();
for (int i = 1; i <= 64; i++) {
// define square position
CGRect square = {horizontalOffset, verticalOffset, squareSize, squareSize};
// set square to be light or dark in colour
if ([nextSquareColour isEqualToString:@"dark"]) {
// dark square
CGContextSetRGBFillColor(context, 0.05, 0.05, 0.05, 0.80);
nextSquareColour = @"light";
} else {
// light square
CGContextSetRGBFillColor(context, 0.95, 0.95, 0.95, 0.80);
nextSquareColour = @"dark";
}
CGContextSetStrokeColorWithColor(context, [UIColor
clearColor].CGColor);
CGContextFillRect(context, square);
CGContextStrokeRect(context, square);
// set up colour and position of next square
horizontalOffset = horizontalOffset + squareSize;
if (i % 8 == 0) {
verticalOffset = verticalOffset + squareSize;
horizontalOffset = 0;
nextSquareColour = @"dark";
}
if (i % 16 == 0) {
nextSquareColour = @"light";
}
} // end for-loop
}
答案 0 :(得分:1)
如果您只想填充纯色的方形单元格,则可以对每个单元格使用UIView
或CALayer
。为每个视图(图层)设置适当的背景,并将它们添加到superview(超级图层)。这将比绘制电路板消耗更少的内存。
其他选项是使用CAReplicatorLayer
。但我认为第一种选择没有任何好处。
答案 1 :(得分:1)
除了UI之外,您要多次比较字符串。你可以通过以下方式避免它:
for(int row = 0; row < 8; row++)
{
for(int column = 0; column < 8; column++)
{
CGRect square = {horizontalOffset + (column * squareSize),
verticalOffset + (row * squareSize),
squareSize,
squareSize};
if((row + column) % 2 == 0)
CGContextSetRGBFillColor(context, 0.05, 0.05, 0.05, 0.80);
else
CGContextSetRGBFillColor(context, 0.95, 0.95, 0.95, 0.80);
CGContextSetStrokeColorWithColor(context, [UIColor
clearColor].CGColor);
CGContextFillRect(context, square);
CGContextStrokeRect(context, square);
}
}
答案 2 :(得分:1)
除非导致视图在有限的时间间隔内重绘太多次,否则不应出现性能问题。从它的外观(棋盘)看,你的情况不应该发生。
你可以避免的一件事是绘制两种方形颜色。例如,您可以将深色设置为背景,并仅绘制浅色方块。 这是一个小课程:(颜色,大小和起始位置可设置)
@interface ChessView : UIView
@property (nonatomic, strong) UIColor *lightSquareColor; // default is 0.95f 0.95f 0.95f 0.8f
@property (nonatomic, strong) UIColor *darkSquareColor; // default is 0.05f 0.05f 0.05f 0.8f
@property (nonatomic) CGFloat squareSize; // default is 40.0f
@property (nonatomic) CGPoint boardOrigin; // default is {0.0f, 0.0f}
@end
@implementation ChessView
@synthesize lightSquareColor = _lightSquareColor;
@synthesize darkSquareColor = _darkSquareColor;
#pragma mark - UIView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self baseInit];
}
return self;
}
- (void)baseInit
{
self.squareSize = 40.0f;
self.boardOrigin = CGPointZero;
}
- (void)drawRect:(CGRect)rect
{
CGFloat verticalOffset = self.boardOrigin.y;
CGFloat horizontalOffset = self.boardOrigin.x;
CGFloat squareSize = self.squareSize;
CGContextRef context = UIGraphicsGetCurrentContext();
// draw background with dark color
[self.darkSquareColor setFill];
CGContextFillRect(context, CGRectMake(horizontalOffset, verticalOffset, squareSize * 8.0f, squareSize * 8.0f));
// Create a path and add light squares to it
CGMutablePathRef path = CGPathCreateMutable();
for (int i = 1; i <= 32; i++) {
CGRect square = {horizontalOffset, verticalOffset, squareSize, squareSize};
CGPathAddRect(path, NULL, square);
horizontalOffset = horizontalOffset + 2.0f * squareSize;
if (i % 4 == 0) {
verticalOffset = verticalOffset + self.squareSize;
horizontalOffset = i % 8 == 0 ? 0.0f : squareSize;
}
}
[self.lightSquareColor setFill];
CGContextAddPath(context, path);
CGPathRelease(path);
CGContextFillPath(context);
}
#pragma mark - Colors
- (UIColor *)lightSquareColor
{
if (!_lightSquareColor) {
_lightSquareColor = [UIColor colorWithRed:0.95f
green:0.95f
blue:0.95f
alpha:0.8f];
}
return _lightSquareColor;
}
- (UIColor *)darkSquareColor
{
if (!_darkSquareColor) {
_darkSquareColor = [UIColor colorWithRed:0.05f
green:0.05f
blue:0.05f
alpha:0.8f];
}
return _darkSquareColor;
}
- (void)setLightSquareColor:(UIColor *)lightSquareColor
{
if (![_lightSquareColor isEqual:lightSquareColor]) {
_lightSquareColor = lightSquareColor;
[self setNeedsDisplay];
}
}
- (void)setDarkSquareColor:(UIColor *)darkSquareColor
{
if (![_darkSquareColor isEqual:darkSquareColor]) {
_darkSquareColor = darkSquareColor;
[self setNeedsDisplay];
}
}
#pragma mark - Metrics
- (void)setBoardOrigin:(CGPoint)boardOrigin
{
if (!CGPointEqualToPoint(_boardOrigin, boardOrigin)) {
_boardOrigin = boardOrigin;
[self setNeedsDisplay];
}
}
- (void)setSquareSize:(CGFloat)squareSize
{
if (_squareSize != squareSize) {
_squareSize = squareSize;
[self setNeedsDisplay];
}
}
@end
答案 3 :(得分:1)
您可以使用直线破折号来简化整个事情。但我没有检查是否更高效。 类似的东西:
- (void)drawRect:(CGRect)rect {
int verticalOffset = 40;
int horizontalOffset = 0;
int squareSize = 40;
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat dashes[2] = { squareSize, squareSize};
CGRect boardRect = {horizontalOffset, verticalOffset, squareSize * 8, squareSize * 8};
CGFloat halfSquareSize = squareSize * .5;
// Fill board with light color
CGContextSetRGBFillColor(context, 0.95, 0.95, 0.95, 0.80);
CGContextFillRect(context, boardRect);
// Draw dark squares only by using line dashes
CGContextSetRGBFillColor(context, 0.05, 0.05, 0.05, 0.80);
CGContextSetLineWidth(context, squareSize);
for (int i = 0; i < 8; i++)
{
if ((i & 0x1) == 0)
{
CGContextSetLineDash(context, squareSize, dashes, 2);
}
else
{
CGContextSetLineDash(context, 0, dashes, 2);
}
CGContextMoveToPoint(context, horizontalOffset, verticalOffset + i * squareSize + halfSquareSize);
CGContextAddLineToPoint(context, horizontalOffset + 8 * squareSize, verticalOffset + i * squareSize + halfSquareSize);
CGContextDrawPath(context, kCGPathFillStroke);
}
}
答案 4 :(得分:0)
为什么不只有一张包含整个棋盘的黎明前图像