从父UIView中移除CALayers

5

有很多类似的问题,但没有有效的答案。

我要像下面这样向UIView添加新的CALayer:

    func placeNewPicture() {
        let newPic = CALayer()
        newPic.contents = self.pictureDragging.contents
        newPic.frame = CGRect(x: pictureScreenFrame.origin.x - pictureScreenFrame.width/2, y: pictureScreenFrame.origin.y - pictureScreenFrame.height/2, width: pictureScreenFrame.width, height: pictureScreenFrame.height)
        self.drawingView.layer.addSublayer(newPic)
    }

尝试使用以下方法去除它们:

    func deleteDrawing() {

        for layer in self.drawingView.layer.sublayers {
            layer.removeFromSuperlayer()
        }
    }

成功移除图片,但是应用程序在下一次触摸屏幕时崩溃,并调用主函数,但调试器中没有任何输出。有很多类似的情况,即在移除子层之后不久应用程序将崩溃。

正确的方法是什么,可以从其父视图中移除CALayers?


粘贴崩溃日志。如果没有一些方法或对象尝试再次访问已释放的图层,那么删除CALayers不会导致崩溃。 - Wingzero
如果@Leo的答案没有解决问题,那么你可能会崩溃,因为在删除层时正在修改迭代的数组。倒序迭代图层,这应该可以解决问题。 - rebello95
1个回答

11

我认为错误在于您删除了所有子层,而不是您添加的那些子层。 保留一个属性以保存您添加的子层。

    var layerArray = NSMutableArray()

那么尝试一下

func placeNewPicture() {
    let newPic = CALayer()
    newPic.contents = self.pictureDragging.contents
    newPic.frame = CGRect(x: pictureScreenFrame.origin.x - pictureScreenFrame.width/2, y: pictureScreenFrame.origin.y - pictureScreenFrame.height/2, width: pictureScreenFrame.width, height: pictureScreenFrame.height)
    layerArray.addObject(newPic)
    self.drawingView.layer.addSublayer(newPic)
}
func deleteDrawing() {

    for layer in self.drawingView.layer.sublayers {
        if(layerArray.containsObject(layer)){
            layer.removeFromSuperlayer()
            layerArray.removeObject(layer)
        }
    }
}

根据Leo Dabus的建议更新,您也可以只设置层的名称。

newPic.name = "1234"

然后检查

func deleteDrawing() {

    for layer in self.drawingView.layer.sublayers {
        if(layer.name == "1234"){
            layerArray.removeObject(layer)
        }
    }
}

Leo,这个很好用。我已经测试了大约10分钟,到目前为止没有崩溃。 - jwade502
2
你可以为图层设置一个名称。https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CALayer_class/index.html#//apple_ref/occ/instp/CALayer/name - Leo Dabus
2
@LeoDabus 感谢您的建议,我已经更新了我的答案。 - Leo
Leo,你的解决方案很棒,但是update deleteDrawing应该是if(layer.name == "1234") {layer.removeFromSuperlayer() }。 - Wangdu Lin
唯一能够阻止那个臭名昭著的崩溃的事情。 - grantespo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接