我想用以下路径绘制网格&用户可以填充它,如 ios 中的图像所示

Posted

技术标签:

【中文标题】我想用以下路径绘制网格&用户可以填充它,如 ios 中的图像所示【英文标题】:I want to draw grid with following path & user can fill that as shown in image in ios 【发布时间】:2016-11-11 13:07:08 【问题描述】:

我想在所有设备的第一张图像中绘制网格,并且用户只能通过拖动网格作为第二张图像来填充路径,我尝试了很多东西但没有使用它,请建议我应该如何制作?

【问题讨论】:

【参考方案1】:

关键思想

    首先,您需要覆盖UIView,这样您才能利用某些东西。 第二个你需要知道heightwidth在绘制整个棋盘之前。 第三个需要维护一个数据结构,该结构将跟踪在哪里绘制和在哪里不绘制。

第一点很简单,我们需要重写UIView 类。我们将在drawRect 方法中完成大部分任务。举例来说,扩展类名是CustomGridView

在讨论第 2 点之前,我们先讨论第 3 点。

每个网格可以处于三种状态之一,

空(没有围绕此网格绘制框) 环绕(围绕此网格绘制的框) 填充包围(方框绘制并用蓝色填充)

所以我们将为这三个状态声明一个enum

typedef enum
    EMPTY_BLOCK = 0,
    SURROUNDED_BLOCK,
    FILLED_SURROUNDED_BLOCK

现在我们将使用如下声明的二维数字数组来跟踪网格:

 NSMutableArray<NSMutableArray<NSNumber*>*>* gridStructure;  

使用EMPTY_BLOCKSURROUNDED_BLOCK 初始化数组,因为它希望在网格中显示。例如,假设您想要一个高度为 5 块和宽度为 4 块的网格。所有外部块都是SURROUNDED_BLOCK,那么数组应该是这样的。

1、1、1、1

1、0、0、1

1、0、0、1

1、0、0、1

1、1、1、1

现在,当用户触摸网格时,用FILLED_SURROUNDED_BLOCK 填充该网格位置。

现在最重要的#2,最乏味的事情。在drawRect 中,您将使用rect 指定,这将表示CustomGridViewheightwidth。在这里,您将根据数组坐标绘制网格。您必须将整个视图拆分为 grid_width*grid_height 空格。然后根据二维数组的值进行绘图。例如

如果你找到了EMPTY_BLOCK,那么什么都不画,其余的如下。

其他资源:

    添加UIPangestureRecognizer 以跟踪用户触摸路径并跟踪二维网格数组中的位置。更新二维数组网格后,更新视图的drawRect 调用[self setNeedsDisplay]

    绘制 4 行第二条代表 FILLED_SURROUNDED_BLOCK 事物。

    如何画线回答here

祝你好运。

基于上述思路,这里是一个示例实现

GridView.h

#import <UIKit/UIKit.h>

IB_DESIGNABLE @interface GridView : UIView
@end

GridView.m

#import "GridView.h"

enum GRID_BOX_TYPE

    GRID_BOX_BLANK = 0,
    GRID_BOX_RED,
    GRID_BOX_BLUE
;

#define NUMBER_OF_ROWS  5
#define NUMBER_OF_COLS  4

#define GRID_LINE_WIDTH 2

@implementation GridView

    enum GRID_BOX_TYPE twoDGrid[NUMBER_OF_ROWS][NUMBER_OF_COLS];
    CGSize gridSizeRatio;

#pragma mark init methods
-(id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if(self)
        //do initialization here
        [self commonInitializer];
    
    return self;


-(id)initWithCoder:(NSCoder *)aDecoder

    self = [super initWithCoder:aDecoder];
    if(self)
        //do initialization here
        [self commonInitializer];
    
    return self;


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect 
    
    CGContextRef context = UIGraphicsGetCurrentContext();
//    CGContextClearRect(context, rect);
    
    //global settings
    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    
    
    for(int i=0;i<NUMBER_OF_ROWS;i++)
    
        for(int j=0;j<NUMBER_OF_COLS;j++)
        
            enum GRID_BOX_TYPE blockType = twoDGrid[i][j];
            
            switch (blockType) 
                case GRID_BOX_BLANK :
                
                    //draw white box
                    CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
            
                    CGContextStrokeRectWithWidth(context, CGRectMake(j * rect.size.width * gridSizeRatio.width,
                                                         i * rect.size.height * gridSizeRatio.height,
                                                         rect.size.width * gridSizeRatio.width - GRID_LINE_WIDTH,
                                                         rect.size.height * gridSizeRatio.height - GRID_LINE_WIDTH), GRID_LINE_WIDTH);
                    CGContextDrawPath(context, kCGPathFill);
                
                    break;
                case GRID_BOX_RED:
                
                    //draw red box
                    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
                    
                    CGContextStrokeRectWithWidth(context, CGRectMake(j * rect.size.width * gridSizeRatio.width,
                                                         i * rect.size.height * gridSizeRatio.height,
                                                         rect.size.width * gridSizeRatio.width - GRID_LINE_WIDTH,
                                                         rect.size.height * gridSizeRatio.height - GRID_LINE_WIDTH), GRID_LINE_WIDTH);
                    
                    CGContextDrawPath(context, kCGPathFill);
                
                    break;
                case GRID_BOX_BLUE:
                
                    //draw blue box
                    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
                    
                    CGContextStrokeRectWithWidth(context, CGRectMake(j * rect.size.width * gridSizeRatio.width,
                                                         i * rect.size.height * gridSizeRatio.height,
                                                         rect.size.width * gridSizeRatio.width - GRID_LINE_WIDTH,
                                                         rect.size.height * gridSizeRatio.height - GRID_LINE_WIDTH), GRID_LINE_WIDTH);
                    CGContextDrawPath(context, kCGPathFill);
                
                    break;
                default:
                    break;
            
            
            
        
    


#pragma mark private initializer
-(void)commonInitializer

    twoDGrid[0][0]= GRID_BOX_RED;
    twoDGrid[0][1]= GRID_BOX_RED;
    twoDGrid[0][2]= GRID_BOX_RED;
    twoDGrid[0][3]= GRID_BOX_RED;
    twoDGrid[1][0]= GRID_BOX_RED;
    twoDGrid[1][1]= GRID_BOX_BLANK;
    twoDGrid[1][2]= GRID_BOX_BLANK;
    twoDGrid[1][3]= GRID_BOX_RED;
    twoDGrid[2][0]= GRID_BOX_RED;
    twoDGrid[2][1]= GRID_BOX_BLUE;
    twoDGrid[2][2]= GRID_BOX_BLUE;
    twoDGrid[2][3]= GRID_BOX_RED;
    twoDGrid[3][0]= GRID_BOX_RED;
    twoDGrid[3][1]= GRID_BOX_BLANK;
    twoDGrid[3][2]= GRID_BOX_BLANK;
    twoDGrid[3][3]= GRID_BOX_RED;
    twoDGrid[4][0]= GRID_BOX_RED;
    twoDGrid[4][1]= GRID_BOX_RED;
    twoDGrid[4][2]= GRID_BOX_RED;
    twoDGrid[4][3]= GRID_BOX_RED;
    
    gridSizeRatio = CGSizeMake(1.0/NUMBER_OF_COLS, 1.0/NUMBER_OF_ROWS);

@end

预览

【讨论】:

嘿 Rahul,我明白了你的概念,但请提供任何相同的示例代码。 嘿,这是 Ratul 而不是 Rahul:P,顺便说一句,请将答案标记为已接受,因为它符合您的要求 :)。

以上是关于我想用以下路径绘制网格&用户可以填充它,如 ios 中的图像所示的主要内容,如果未能解决你的问题,请参考以下文章

如何用增加的半径填充圆?

使用 QML 绘制 SVG

重复网格中的用户输入以填充动态下拉列表

Tkinter 网格动态布局

如何为 CAShapeLayer 路径和填充颜色设置动画

如何绘制不同颜色的填充路径/形状