我有两个并排的函数,它们循环不断地绘制两个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 {
答案 0 :(得分:2)
Apple的Drawing and Printing Guide for iOS解释了所有这些,我高度建议在继续使用自定义绘图代码之前阅读它。绝对最低限度,请阅读iOS Drawing Concepts。
部分问题在于您在NSTimer
CircleView
功能中创建并触发drawRect
。绘图调用只能在正确的上下文中进行(这实际上是您试图告诉您的错误)。通过在NSTimer
调用的函数中进行绘制,您实际上正在绘制外部您的drawRect
函数,并且在这种情况下没有有效的绘图上下文。此外,对于代码的方式,每次系统需要重绘视图时,您都将启动新的定时器;随着计时器开始重叠,这可能会很快失控。
然而,只需稍微重新安排,我们就可以做到这一点。
请注意:这不一定是您正在使用圈子动画进行操作的正确方法,但它可以解决您所询问的特定问题关于无效的上下文错误。
取出drawRect
中的所有内容,并将其替换为eraseCircle
和drawCircle
的来电。
从x
和{{1}中取出必须增加y
和eraseX
以及eraseY
和drawCircle
的逻辑然后将其放在eraseCircle
和timerDraw
中。
不要直接在timerErase
和timerDraw
中调用您的绘图代码,而是通过调用setNeedsDisplay()
告诉视图系统您需要重新绘制视图。这会将您的视图标记为需要重新绘制,视图系统会尽快再次自动调用timerErase
函数。
通过覆盖drawRect
让你的计时器重新开始工作并在那里启动它们;如果它们已经在运行,你还应该添加逻辑来阻止它们。
步骤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。