我现在有一个非常简单的应用程序。我在用户手指去的地方画线,当他们抬起手指时,我想清除绘图,当他们再次绘制时显示新线条。
但是,当我第一次清除行时,下一次按下会导致崩溃,没有错误消息。我想我做错了什么小事,但无法弄清楚。这是我的代码:
我收到EXC__BAD_ACCESS消息
var prevX: CGFloat!
var prevY: CGFloat!
var startX: CGFloat = 150
var startY : CGFloat = 450
var reset: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
var pan = UIPanGestureRecognizer(target: self, action: "pan:")
pan.cancelsTouchesInView = false
pan.delegate = self
self.view.addGestureRecognizer(pan)
}
func pan(recognizer:UIPanGestureRecognizer) {
print(self.view.layer)
var state = recognizer.state
if (state == UIGestureRecognizerState.Ended) {
reset = true
var sublayers = self.view.layer.sublayers
for layer in sublayers {
layer.removeFromSuperlayer()
}
} else {
var interval = recognizer.translationInView(self.view)
if (reset) {
reset = false
prevX = CGFloat(startX + interval.x)
prevY = CGFloat(startY + interval.y)
}
var newPointX = startX + interval.x
var newPointY = startY + interval.y
var path = UIBezierPath().bezierPathByReversingPath()
path.moveToPoint(CGPoint(x: prevX, y: prevY))
path.addLineToPoint(CGPoint(x:newPointX, y:newPointY))
var shapeLayer = CAShapeLayer()
shapeLayer.path = path.CGPath
shapeLayer.strokeColor = UIColor.blueColor().CGColor
shapeLayer.lineWidth = 1.0
shapeLayer.fillColor = UIColor.clearColor().CGColor
self.view.layer.addSublayer(shapeLayer)
prevX = newPointX
prevY = newPointY
}
}
我不太确定堆栈跟踪出现在哪里。我在 pan 回调的顶部放了一个 print 语句,并且没有被调用,所以我认为它不会发生这种情况。它只是打开
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
给出消息线程 1:EXC_BAD_ACCESS代码=1,地址=0x499e....
再多一点,顶部消息中显示错误消息:
___UIApplicationExtensionGetAccurateShareServicesExtensionForIdentifier_block_invoke_2
0x18c00e3c0: adrp x8, 54568
0x18c00e3c4: ldr x8, [x8, #2248]
0x18c00e3c8: ldr x8, [x8]
0x18c00e3cc: ldr x9, [sp, #56]
0x18c00e3d0: sub x8, x8, x9
0x18c00e3d4: cbnz x8, 0x18c00e3fc ; UIApplicationMain + 1548
0x18c00e3d8: movz w0, #0
我知道这是这条线正在做的事情:
for layer in sublayers {
layer.removeFromSuperlayer()
}
因为如果我删除它,它可以正常工作(只是不清除上一行)
问题是已经有用于view
的子图层,并且您正在将其与添加的子图层一起删除。 您只想移除添加的子图层。 我添加了一个myLayers
数组来保存新的子层,并使用它来删除添加的子层:
var prevX: CGFloat!
var prevY: CGFloat!
var startX: CGFloat = 150
var startY : CGFloat = 450
var reset: Bool = true
var myLayers: [CAShapeLayer] = []
override func viewDidLoad() {
super.viewDidLoad()
var pan = UIPanGestureRecognizer(target: self, action: "pan:")
pan.cancelsTouchesInView = false
pan.delegate = self
self.view.addGestureRecognizer(pan)
}
func pan(recognizer:UIPanGestureRecognizer) {
print(self.view.layer)
var state = recognizer.state
if (state == UIGestureRecognizerState.Ended) {
reset = true
for layer in myLayers {
layer.removeFromSuperlayer()
}
myLayers = []
} else {
var interval = recognizer.translationInView(self.view)
if (reset) {
reset = false
prevX = CGFloat(startX + interval.x)
prevY = CGFloat(startY + interval.y)
}
var newPointX = startX + interval.x
var newPointY = startY + interval.y
var path = UIBezierPath().bezierPathByReversingPath()
path.moveToPoint(CGPoint(x: prevX, y: prevY))
path.addLineToPoint(CGPoint(x:newPointX, y:newPointY))
var shapeLayer = CAShapeLayer()
shapeLayer.path = path.CGPath
shapeLayer.strokeColor = UIColor.blueColor().CGColor
shapeLayer.lineWidth = 1.0
shapeLayer.fillColor = UIColor.clearColor().CGColor
self.view.layer.addSublayer(shapeLayer)
myLayers.append(shapeLayer)
prevX = newPointX
prevY = newPointY
}
}
<</div>
div class="one_answers"> 这是一种需要更少代码并且只使用一层的方法。您不需要删除该图层,只需删除其路径即可。
class ViewController: UIViewController, UIGestureRecognizerDelegate {
var path: UIBezierPath!
var shapeLayer = CAShapeLayer()
override func viewDidLoad() {
super.viewDidLoad()
let pan = UIPanGestureRecognizer(target: self, action: "pan:")
view.addGestureRecognizer(pan)
shapeLayer.strokeColor = UIColor.blueColor().CGColor
shapeLayer.lineWidth = 1.0
shapeLayer.fillColor = UIColor.clearColor().CGColor
view.layer.addSublayer(shapeLayer)
}
func pan(recognizer:UIPanGestureRecognizer) {
if recognizer.state == .Began {
let loc = recognizer.locationInView(view)
path = UIBezierPath()
path.moveToPoint(loc)
}else if recognizer.state == .Changed {
var loc = recognizer.locationInView(view)
path.addLineToPoint(loc)
shapeLayer.path = path.CGPath
}else if recognizer.state == .Ended {
shapeLayer.path = nil
}
}
}