Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 清除视图中的图层会使应用程序在下一次迭代中崩溃_Ios_Objective C_Swift_Uipangesturerecognizer - Fatal编程技术网

Ios 清除视图中的图层会使应用程序在下一次迭代中崩溃

Ios 清除视图中的图层会使应用程序在下一次迭代中崩溃,ios,objective-c,swift,uipangesturerecognizer,Ios,Objective C,Swift,Uipangesturerecognizer,我现在有一个非常简单的应用程序。我在用户手指移动的地方画线,当他们抬起手指时,我想清除图形,当他们再次绘制时,显示新的线 但是,当我第一次清除这些行时,下一次按下会导致崩溃,并且没有错误消息。我觉得我做错了一件小事,但我想不出来。这是我的密码: 我收到一条EXC错误访问消息 var prevX: CGFloat! var prevY: CGFloat! var startX: CGFloat = 150 var startY : CGFloat = 450 var reset: Bool

我现在有一个非常简单的应用程序。我在用户手指移动的地方画线,当他们抬起手指时,我想清除图形,当他们再次绘制时,显示新的线

但是,当我第一次清除这些行时,下一次按下会导致崩溃,并且没有错误消息。我觉得我做错了一件小事,但我想不出来。这是我的密码:

我收到一条EXC错误访问消息

 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 code=1,address=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()
        }

因为如果我删除它,它可以正常工作,只是没有清除前一行

问题是已经有子层可供查看,您正在删除这些子层以及您添加的子层。您只想删除添加的子图层。我添加了一个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

    }
}

这里有一种方法,它需要更少的代码,并且只使用一个层。您不需要删除该层,只需删除其路径即可

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

}

请指出你从哪里得到的异常。我甚至不太确定。它不会进入pan回调。我在开头放了一个print语句,但它没有出现。我用堆栈跟踪更新了这个问题。这看起来是一个非常糟糕的作图方法。为什么每次移动手指时都要添加一个新的贝塞尔路径和层?@rdelmar我想画一条线来显示用户移动手指的位置,有什么更好的方法来实现这一点?哦,这太棒了!非常感谢@rdelmar