使用 CoreGraphics 在 iPhone 上绘制简单的线条

Posted

技术标签:

【中文标题】使用 CoreGraphics 在 iPhone 上绘制简单的线条【英文标题】:Drawing simple lines on iPhone with CoreGraphics 【发布时间】:2011-06-13 11:37:12 【问题描述】:

我想在用户触摸屏幕的位置和触摸结束的位置之间画一条直线。我需要多行,因为如果用户重复触摸-拖动-释放操作,我还需要一个按钮来清除所有行。到目前为止,我在下面有这段代码,但是一旦再次调用它,我就会收到错误:CGContextSetStrokeColor: invalid context 0x0。重复此错误:CGContextBeginPath、CGContextMoveToPoint、CGContextAddLineToPoint、CGContextDrawPath。

有什么想法吗?

- (void)drawRect:(CGRect)rect    
    c = UIGraphicsGetCurrentContext();

    CGFloat black[4] = 0, 0, 
                        0, 1;
    CGContextSetStrokeColor(c, black);
    CGContextBeginPath(c);
    CGContextMoveToPoint(c, 100, 100);
    CGContextAddLineToPoint(c, 100, 200);
    CGContextStrokePath(c);

【问题讨论】:

你也可以设置颜色为([UIColor blackColor].CGColor); 根本不是问题/ 【参考方案1】:

完整代码如下。

/* Set the color that we want to use to draw the line */ 
[[UIColor brownColor] set];
/* Get the current graphics context */ 
CGContextRef currentContext =UIGraphicsGetCurrentContext();
/* Set the width for the line */
CGContextSetLineWidth(currentContext,5.0f);
/* Start the line at this point */ 
CGContextMoveToPoint(currentContext,50.0f, 10.0f);
/* And end it at this point */ 
CGContextAddLineToPoint(currentContext,100.0f, 200.0f);
/* Use the context's current color to draw the line */
CGContextStrokePath(currentContext);

【讨论】:

【参考方案2】:

你还没有定义c的类型:

CGContextRef c = UIGraphicsGetCurrentContext();

【讨论】:

我刚刚下@implemmnation【参考方案3】:

问题是UIGraphicsGetCurrentContext() 将返回一个空引用。 如果要绘制到 UIImage 中,可以按如下方式获取 CGContextRef:

UIGraphicsBeginImageContext(anUIImage);

现在调用UIGraphicsGetCurrentContext() 将不再返回空引用。

...绘图在这里

UIImage* drawnImage = UIGraphicsGetImageFromCurrentImageContext();
// display the image on an view
UIGraphicsEndImageContext();  

【讨论】:

UIGraphicsBeginImageContext() 不能以 UIImage 作为参数调用。【参考方案4】:

我知道这是一个老问题,但根据答案,我在 Swift 中写了以下内容:

override func drawRect(rect: CGRect) 
    super.drawRect(rect)

    UIColor.blackColor().setStroke() // update with correct color

    let path = UIBezierPath()
    path.lineWidth = UIScreen.mainScreen().scale > 1 ? 0.5 : 1

    // change the points to what you need them to be
    let leftPoint = CGPointMake(0, CGRectGetHeight(rect))
    let rightPoint = CGPointMake(CGRectGetWidth(rect), CGRectGetHeight(rect))

    path.moveToPoint(leftPoint)
    path.addLineToPoint(rightPoint)

    path.stroke()

【讨论】:

【参考方案5】:

斯威夫特 3

这是一个完整示例,用于在单独的图像中绘制线条(网格),然后将此图像(作为叠加)添加到现有图像,在本例中称为“boardImage”。

// ----------------------------------------------------------------------------------------
// DRAW LINES ON THE BOARD IMAGE
// ----------------------------------------------------------------------------------------
    private func drawLinesOnBoard() 

        // 1. DEFINE AN OFFSET AND THE SIZE OF ONE GRIDFIELD

        let offSet      : CGFloat = 20
        let fieldWidth  : CGFloat = 60

        // 2. CREATE A IMAGE GRAPHICS CONTEXT AND DRAW LINES ON IT

        UIGraphicsBeginImageContext(boardImage.boundsSize)

        if let currentContext = UIGraphicsGetCurrentContext() 

            currentContext.setLineWidth(1)  // set strokeWidth
            currentContext.setStrokeColor(UIColor.init(colorLiteralRed: 0.85, green: 1, blue: 0.85, alpha: 0.85).cgColor)
            currentContext.setLineJoin(.round)
            currentContext.setLineDash(phase: 1, lengths: [offSet / 4, offSet / 5])

            // VERTICAL LINES
            for multiplyer in (1...5) 

                let startPoint  : CGPoint = CGPoint(x: offSet + CGFloat(multiplyer) * fieldWidth, y: offSet)
                let endPoint    : CGPoint = CGPoint(x: startPoint.x, y: boardImage.frame.height - offSet)

                /* Start the line at this point */
                currentContext.move(to: startPoint)

                /* And end it at this point */
                currentContext.addLine(to: endPoint)
            

            // HORIZONTAL LINES
            for multiplyer in (1...5) 

                let startPoint  : CGPoint = CGPoint(x: offSet, y: offSet + CGFloat(multiplyer) * fieldWidth)
                let endPoint    : CGPoint = CGPoint(x:boardImage.frame.width - offSet, y: startPoint.y)

                /* Start the line at this point */
                currentContext.move(to: startPoint)

                /* And end it at this point */
                currentContext.addLine(to: endPoint)
            

            currentContext.strokePath()

            // 3. CREATE AN IMAGE OF THE DRAWN LINES AND ADD TO THE BOARD

            if let linesImage : UIImage = UIGraphicsGetImageFromCurrentImageContext() 
                let linesImageView : UIImageView = UIImageView(image: linesImage)
                let theCenter : CGPoint = CGPoint(x: boardImage.bounds.width / 2, y: boardImage.bounds.height / 2)
                boardImage.addSubview(linesImageView)
                linesImageView.center = theCenter
                isBoardLinesDrawn = true
            
        

        // 4. END THE GRAPHICSCONTEXT
        UIGraphicsEndImageContext()

【讨论】:

以上是关于使用 CoreGraphics 在 iPhone 上绘制简单的线条的主要内容,如果未能解决你的问题,请参考以下文章

有关iOS使用CoreGraphics部分机型出现背景红块问题

CoreGraphics 替代方案?

CoreGraphics 库在 iOS4 而不是 iOS3 中泄漏?

Instruments 中的 CoreGraphics 导致的大内存占用

使用核心图形的 iPhone 光泽图标

Core Graphics 触摸时画线和删除