7

I am trying to render a line/step graph on Apple Watch using watchOS 2. Unlike iOS 9, watchOS 2 doesn't support Quartz. It only supports Core Graphics. I tried writing some code to draw a line graph but I am getting an error "CGContextRestoreGState: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update."

Following is the piece of code I used:

import WatchKit
import Foundation
import UIKit

class InterfaceController: WKInterfaceController{
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        let path = UIBezierPath()
        let startPoint =  CGPointMake(0.0, 0.0)
        path.moveToPoint(startPoint)
        let nextPoint = CGPointMake(20.0, 20.0)
        path.addLineToPoint(nextPoint)
        path.lineWidth = 1.0
        UIColor.whiteColor().setStroke()
        path.stroke()
    }

    override func willActivate() {
        super.willActivate()

    }

    override func didDeactivate() {
        super.didDeactivate()
    }
}

My end result should be something like Stocks app present on Apple Watch. Wwhenever user clicks on particular stock, he will be able to view/visualize the statistics of that stock. Can anybody please help me in achieving this.

4

5 回答 5

11

我通过以下步骤成功渲染线条:

  • 创建一个基于位图的图形上下文,并使用UIGraphicsBeginImageContext.
  • 融入上下文。
  • 从上下文中提取 CGImageRef 并将其转换为 UIImage 对象。
  • 在 WKInterfaceGroup 或 WKInterfaceImage 上显示图像。

代码:

// Create a graphics context
let size = CGSizeMake(100, 100)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()

// Setup for the path appearance
CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().CGColor)
CGContextSetLineWidth(context, 4.0)

// Draw lines
CGContextBeginPath (context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 100, 100);
CGContextMoveToPoint(context, 0, 100);
CGContextAddLineToPoint(context, 100, 0);
CGContextStrokePath(context);

// Convert to UIImage
let cgimage = CGBitmapContextCreateImage(context);
let uiimage = UIImage(CGImage: cgimage!)

// End the graphics context
UIGraphicsEndImageContext()

// Show on WKInterfaceImage
image.setImage(uiimage)

image是 WKInterfaceImage 属性。这个对我有用。

我也可以在 watchOS 上使用 UIBezierPath 进行绘制,如下所示:

// Create a graphics context
let size = CGSizeMake(100, 100)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
UIGraphicsPushContext(context!)

// Setup for the path appearance
UIColor.greenColor().setStroke()
UIColor.whiteColor().setFill()

// Draw an oval
let rect = CGRectMake(2, 2, 96, 96)
let path = UIBezierPath(ovalInRect: rect)
path.lineWidth = 4.0
path.fill()
path.stroke()

// Convert to UIImage
let cgimage = CGBitmapContextCreateImage(context);
let uiimage = UIImage(CGImage: cgimage!)

// End the graphics context
UIGraphicsPopContext()
UIGraphicsEndImageContext()

image.setImage(uiimage)

您可以在此处查看示例代码。

于 2015-07-14T11:19:46.387 回答
2

这是watchOS 3中的代码

  // Create a graphics context
        let size = CGSize(width:self.contentFrame.size.width, height:100)


        UIGraphicsBeginImageContext(size)
        let context = UIGraphicsGetCurrentContext()

        // Setup for the path appearance
        context!.setStrokeColor(UIColor.white.cgColor)
        context!.setLineWidth(4.0)

        // Draw lines
        context!.beginPath ();

        context?.move(to: CGPoint())
        context?.addLine(to: CGPoint(x: 100, y: 100))
        context?.addLine(to: CGPoint(x: 0, y: 100))
        context?.addLine(to: CGPoint(x: 100, y: 0))

        context!.strokePath();

        // Convert to UIImage
        let cgimage = context!.makeImage();
        let uiimage = UIImage(cgImage: cgimage!)

        // End the graphics context
        UIGraphicsEndImageContext()

        self.graphGroup.setBackgroundImage(uiimage)
于 2016-08-30T09:14:52.467 回答
0

这里的上下文不是 CGContext,因此你有问题。我认为您不能直接在 Apple Watch 上使用 Core Graphics。

于 2015-07-08T03:27:27.017 回答
0

这是一个示例项目,展示了如何在 WatchKit 2.0 上制作动态图表

https://github.com/vlm/ExampleWatchGraph

它的要点在GraphPainter.swift文件中,其中 CoreGraphics 用于绘制到屏幕外缓冲区(如 @shu223 建议的那样),然后在 WKInterfaceImage 中显示此缓冲区。

动画手表界面 GIF

于 2015-11-30T18:03:55.467 回答