这是我在应用程序中绘制棋盘的方式。 除了使用静态图像之外,还有没有更有效或更明智的方法来做到这一点?
- (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
}
除非导致视图在有限的时间间隔内重绘次数过多,否则不应出现性能问题。从它的外观(棋盘)来看,这不应该发生在您的情况下。
您可以避免的一件事是绘制两种正方形颜色。例如,您可以将深色设置为背景并仅绘制浅色方块。这里有一个小类可以做到这一点:(颜色,大小和起始位置是可设置的)
@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
除了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);
}
}
如果您只想用纯色填充方形单元格,则可以为每个单元格使用UIView
或CALayer
。为每个视图(图层)设置适当的背景,并将其添加到超级视图(超级图层)中。这将比绘制电路板消耗更少的内存。
另一种选择是使用 CAReplicatorLayer
.但是我认为与第一种选择相比,这里没有任何好处。
您可以使用线条破折号来简化整个事情。但我没有检查它的性能是否更高。像这样:
- (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);
}
}
为什么不拥有一个包含整个板的黎明前图像