有没有比这更有效的棋盘方法



这是我在应用程序中绘制棋盘的方式。 除了使用静态图像之外,还有没有更有效或更明智的方法来做到这一点?

- (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);
     }
}

如果您只想用纯色填充方形单元格,则可以为每个单元格使用UIViewCALayer。为每个视图(图层)设置适当的背景,并将其添加到超级视图(超级图层)中。这将比绘制电路板消耗更少的内存。

另一种选择是使用 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);
    }
}

为什么不拥有一个包含整个板的黎明前图像

相关内容

  • 没有找到相关文章

最新更新