省略UIColor.setFill()错误消息?

时间:2014-09-15 03:31:12

标签: ios swift uicolor

我有两个并排的函数,它们循环不断地绘制两个UIBezierPaths,事实是,每个函数都有不同的颜色,所以我经常需要重申UIColor.blackColor().setFill()UIColor(patternImage: UIImage(named: "normalpaper.jpg")).setFill(),这就是缺点它是否使得控制台无法阅读,因为它无休止地发出警告信息。

<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.

因此,这是我的问题,是否有一种方法可以通过此警告消息向我的控制台发送垃圾邮件?也许是一种使警告信息不会出现的方法? (无法通过搜索找到一个)或者可能是省略消息的方法?任何输入都非常感谢,感谢您阅读-Zach。

-

如果你需要抽奖functions,那么它们就在下面

func drawCircle() {

    //Setting the draw color
    UIColor.blackColor().setFill()

    // Creating the rectangle's size
    var drawRect = roundDrawRect(10.0, angle: 7)

    //Incrementing the coords
    ++y
    ++x

    //Drawing the rectangle
    drawRect.fill()

}

func eraseCircle() {

    //Setting the eraser color
    UIColor(patternImage: UIImage(named: "normalpaper.jpg")).setFill()

    //Decrementing the coords
    eraseX = x - 2
    eraseY = y - 2

    // Creating the rectangle's size
    var eraseRect = roundEraseRect(10.0, angle: 7)

    //Drawing the rectangle
    eraseRect.fill()

}

下面的Full CircleView课程 (我对编程还很新,所以效率可能很低)

//Creating a view capable of painting the circle
class CircleView: UIView {

//Starting X Pos
var x: CGFloat = 100
var eraseX: CGFloat = 100

//Starting Y Pos
var y: CGFloat = 100
var eraseY: CGFloat = 100

//Starting the loop of functions
override func drawRect(rect: CGRect) {

    //Creating the looping draw timer
    NSTimer.scheduledTimerWithTimeInterval(
        0.2,
        target: self,
        selector: Selector("timerDraw"),
        userInfo: nil,
        repeats: true)

    //Creating the looping erase timer
    NSTimer.scheduledTimerWithTimeInterval(
        0.3,
        target: self,
        selector: Selector("timerErase"),
        userInfo: nil,
        repeats: true)

}

func drawCircle() {

    //Setting the draw color
    UIColor.blackColor().setFill()

    // Creating the rectangle's size
    var drawRect = roundDrawRect(10.0, angle: 7)

    //Incrementing the coords
    ++y
    ++x

    //Drawing the rectangle
    drawRect.fill()

}

func eraseCircle() {

    //Setting the eraser color
    UIColor(patternImage: UIImage(named: "normalpaper.jpg")).setFill()

    //Decrementing the coords
    eraseX = x - 2
    eraseY = y - 2

    // Creating the rectangle's size
    var eraseRect = roundEraseRect(10.0, angle: 7)

    //Drawing the rectangle
    eraseRect.fill()

}

func timerDraw(){

    //DO DRAW LOOP HERE
    drawCircle()

}

func timerErase(){

    //DO ERASE LOOP HERE
    eraseCircle()

}

//Defining the rounded rect erasing (Circle)
func roundEraseRect(radius: CGFloat, angle: CGFloat) -> UIBezierPath {

    //Creating the rounded rect (Circle)
    var roundedRect = UIBezierPath()

    roundedRect.moveToPoint(CGPointMake(eraseX,eraseY))
    println(CGPointMake(eraseX,eraseY))

    roundedRect.addArcWithCenter(CGPointZero, radius: radius,
        startAngle: 0, endAngle: angle ,
        clockwise: true)

    return roundedRect
}

//Defining the rounded rect drawing (Circle)
func roundDrawRect(radius: CGFloat, angle: CGFloat) -> UIBezierPath {

    //Creating the rounded rect (Circle)
    var roundedRect = UIBezierPath()

    roundedRect.moveToPoint(CGPointMake(x,y))

    roundedRect.addArcWithCenter(CGPointZero, radius: radius,
        startAngle: 0, endAngle: angle ,
        clockwise: true)

    return roundedRect
}




}

class ViewController: UIViewController {

1 个答案:

答案 0 :(得分:2)

Apple的Drawing and Printing Guide for iOS解释了所有这些,我高度建议在继续使用自定义绘图代码之前阅读它。绝对最低限度,请阅读iOS Drawing Concepts

部分

问题在于您在NSTimer CircleView功能中创建并触发drawRect。绘图调用只能在正确的上下文中进行(这实际上是您试图告诉您的错误)。通过在NSTimer调用的函数中进行绘制,您实际上正在绘制外部您的drawRect函数,并且在这种情况下没有有效的绘图上下文。此外,对于代码的方式,每次系统需要重绘视图时,您都将启动新的定时器;随着计时器开始重叠,这可能会很快失控。

然而,只需稍微重新安排,我们就可以做到这一点。

请注意:这不一定是您正在使用圈子动画进行操作的正确方法,但它可以解决您所询问的特定问题关于无效的上下文错误。

  1. 取出drawRect中的所有内容,并将其替换为eraseCircledrawCircle的来电。

  2. x和{{1}中取出必须增加yeraseX以及eraseYdrawCircle的逻辑然后将其放在eraseCircletimerDraw中。

  3. 不要直接在timerErasetimerDraw中调用您的绘图代码,而是通过调用setNeedsDisplay()告诉视图系统您需要重新绘制视图。这会将您的视图标记为需要重新绘制,视图系统会尽快再次自动调用timerErase函数。

  4. 通过覆盖drawRect让你的计时器重新开始工作并在那里启动它们;如果它们已经在运行,你还应该添加逻辑来阻止它们。

  5. 步骤1和3是使您的错误消失的关键位。

    这样的事情:

    didMoveToSuperview

    至于实现您正在尝试的动画的最佳方式,您可以看一下只绘制一次圆,然后在//Creating a view capable of painting the circle class CircleView: UIView { // Timers var drawTimer: NSTimer? var eraseTimer: NSTimer? //Starting X Pos var x: CGFloat = 100 var eraseX: CGFloat = 100 //Starting Y Pos var y: CGFloat = 100 var eraseY: CGFloat = 100 override func drawRect(rect: CGRect) { eraseCircle() drawCircle() } override func didMoveToSuperview() { // If we have active timers, stop them if var drawTimer = self.drawTimer { // This stops the timer drawTimer.invalidate() self.drawTimer = nil } if var eraseTimer = self.eraseTimer { // This stops the timer eraseTimer.invalidate() self.eraseTimer = nil } // If we're actually part of the view hierarchy, start the timers if self.superview != nil { //Creating the looping draw timer self.drawTimer = NSTimer.scheduledTimerWithTimeInterval( 0.2, target: self, selector: Selector("timerDraw"), userInfo: nil, repeats: true) //Creating the looping erase timer self.eraseTimer = NSTimer.scheduledTimerWithTimeInterval( 0.3, target: self, selector: Selector("timerErase"), userInfo: nil, repeats: true) } } func drawCircle() { //Setting the draw color UIColor.blackColor().setFill() // Creating the rectangle's size var drawRect = roundDrawRect(10.0, angle: 7) //Drawing the rectangle drawRect.fill() } func eraseCircle() { //Setting the eraser color UIColor(patternImage: UIImage(named: "normalpaper.jpg")).setFill() // Creating the rectangle's size var eraseRect = roundEraseRect(10.0, angle: 7) //Drawing the rectangle eraseRect.fill() } func timerDraw(){ //Incrementing the coords ++y ++x self.setNeedsDisplay() } func timerErase(){ //Decrementing the coords eraseX = x - 2 eraseY = y - 2 self.setNeedsDisplay() } //Defining the rounded rect erasing (Circle) func roundEraseRect(radius: CGFloat, angle: CGFloat) -> UIBezierPath { //Creating the rounded rect (Circle) var roundedRect = UIBezierPath() roundedRect.moveToPoint(CGPointMake(eraseX,eraseY)) println(CGPointMake(eraseX,eraseY)) roundedRect.addArcWithCenter(CGPointZero, radius: radius, startAngle: 0, endAngle: angle , clockwise: true) return roundedRect } //Defining the rounded rect drawing (Circle) func roundDrawRect(radius: CGFloat, angle: CGFloat) -> UIBezierPath { //Creating the rounded rect (Circle) var roundedRect = UIBezierPath() roundedRect.moveToPoint(CGPointMake(x,y)) roundedRect.addArcWithCenter(CGPointZero, radius: radius, startAngle: 0, endAngle: angle , clockwise: true) return roundedRect } } 中移动计时器上的整个视图。或者,可能更好,使用Core Animation。或者,如果您的最终产品将成为一款游戏(甚至是游戏),请查看Sprite Kit