绘制线与触摸位置收缩和褪色到背景Swift 3.0

问题描述:

我遇到了Swift 3.0上的一个奇怪的错误,从而我成功绘制到位于UIView内的UIImageView,但是当我绘制先前绘制的线开始褪色并收缩到UIImageView的顶部,并变得非常模糊,如附图所示。 Beginning of DrawingImage becoming blurry绘制线与触摸位置收缩和褪色到背景Swift 3.0

我希望可以提供任何帮助/指导。

class DrawView: UIView { 
    var drawArea: UIImageView! 
    var clearDrawArea: UIButton! 
    var lastTouch = CGPoint.zero 

    init(){ 
     super.init(frame: CGRect(x: UIScreen.main.bounds.width*0.135, y:UIScreen.main.bounds.height*0.05, width: UIScreen.main.bounds.width*0.8, height: UIScreen.main.bounds.height*0.9)) 
     drawArea = UIImageView(frame: CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.bounds.width*0.9, height: self.bounds.height*0.86)) 
     drawArea.backgroundColor = UIColor.white 

     let buttonWidth = self.bounds.width*0.2 
     let buttonHeight = self.bounds.height*0.1 
     clearDrawArea = UIButton(frame: CGRect(x: (self.bounds.width*0.61)-(buttonWidth/2), y: self.bounds.height*0.94, width: buttonWidth, height: buttonHeight)) 
     clearDrawArea.setTitle("Clear Draw Area", for: .normal) 
     clearDrawArea.backgroundColor = UIColor(red: 49/255, green: 200/255, blue: 134/255, alpha: 255) 
     clearDrawArea.addTarget(self, action: #selector(resetImage), for: .touchUpInside) 

     self.addSubview(clearDrawArea) 
     self.addSubview(drawArea) 

    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

     if let firstTouch = touches.first{ 

      lastTouch = firstTouch.location(in: drawArea) 
     } 

    } 
    func drawLines(_ from: CGPoint, to: CGPoint){ 
     UIGraphicsBeginImageContext(drawArea.frame.size) 
     let context = UIGraphicsGetCurrentContext() 

     context?.move(to: CGPoint(x: from.x, y: from.y)) 
     context?.addLine(to: CGPoint(x: to.x, y: to.y)) 

     context?.setLineCap(.round) 
     context?.setLineWidth(3) 
     context?.setStrokeColor(UIColor.black.cgColor) 

     context?.strokePath() 

     drawArea.image?.draw(in: drawArea.bounds) 
     drawArea.image = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
    } 
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 


     if let firstTouch = touches.first{ 
      let touchLocation = firstTouch.location(in: drawArea) 
      drawLines(lastTouch, to: touchLocation) 

      lastTouch = touchLocation 
     } 
    } 

    func resetImage(){ 

     drawArea.image = nil    
    } 
} 
+0

你想用这段代码实现什么? – jegadeesh

+0

谢谢你的帮助。我只是试图让用户只需在屏幕上画出他们触摸过的所有东西,并将其留在后面。当我在视图控制器类中使用整个屏幕的边界实现代码时,它的工作原理如下,但是当我试图限制只是一个UIView它不起作用。 – Kawalski968

改变了你的代码位尝试以下..

class DrawView: UIView { 
var drawArea: UIImageView! 
var clearDrawArea: UIButton! 
var lastTouch = CGPoint.zero 
let pathAnimation: CABasicAnimation = CABasicAnimation(keyPath:"animation") 
let tempPathLayer: CAShapeLayer = CAShapeLayer() 
var lineLayer:CAShapeLayer=CAShapeLayer() 
init(){ 
    super.init(frame: CGRect(x: UIScreen.main.bounds.width*0.135, y:UIScreen.main.bounds.height*0.05, width: UIScreen.main.bounds.width*0.8, height: UIScreen.main.bounds.height*0.9)) 
    drawArea = UIImageView(frame: CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.bounds.width*0.9, height: self.bounds.height*0.86)) 
    drawArea.backgroundColor = UIColor.white 

    let buttonWidth = self.bounds.width*0.2 
    let buttonHeight = self.bounds.height*0.1 
    clearDrawArea = UIButton(frame: CGRect(x: (self.bounds.width*0.61)-(buttonWidth/2), y: self.bounds.height*0.94, width: buttonWidth, height: buttonHeight)) 
    clearDrawArea.setTitle("Clear Draw Area", for: .normal) 
    clearDrawArea.backgroundColor = UIColor(red: 49/255, green: 200/255, blue: 134/255, alpha: 255) 
    clearDrawArea.addTarget(self, action: #selector(resetImage), for: .touchUpInside) 

    self.addSubview(clearDrawArea) 
    self.addSubview(drawArea) 

} 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 

    //fatalError("init(coder:) has not been implemented") 
} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

    if let firstTouch = touches.first{ 

     lastTouch = firstTouch.location(in: drawArea) 
    } 

} 
func drawLines(_ from: CGPoint, to: CGPoint){ 
    UIGraphicsBeginImageContext(drawArea.frame.size) 

    //let context = UIGraphicsGetCurrentContext() 
    let tempPath: UIBezierPath = UIBezierPath() 
    var lineLayer:CAShapeLayer=CAShapeLayer() 
    tempPath.move(to: from) 
    tempPath.addLine(to: to) 
    let strokeColor = UIColor.red 
    UIColor.blue.setFill() 
    strokeColor.setStroke() 

    let tempPathLayer: CAShapeLayer = CAShapeLayer() 
    tempPathLayer.frame = self.bounds 
    tempPathLayer.position=self.layer.position 
    tempPathLayer.strokeColor = UIColor.green.cgColor 
    tempPathLayer.fillColor = UIColor.red.cgColor 
    tempPathLayer.lineWidth = 1.0 
    tempPathLayer.path = tempPath.cgPath 
    lineLayer=tempPathLayer 
    pathAnimation.beginTime=CACurrentMediaTime() 
    pathAnimation.duration = 2 
    pathAnimation.fromValue = NSNumber(value: 0.0) 
    pathAnimation.toValue = NSNumber(value:1.0) 

    lineLayer.add(pathAnimation, forKey: "animation") 
    self.layer.addSublayer(lineLayer) 

    drawArea.image?.draw(in: drawArea.bounds) 
    drawArea.image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 


    if let firstTouch = touches.first{ 
     let touchLocation = firstTouch.location(in: drawArea) 
     drawLines(lastTouch, to: touchLocation) 

     lastTouch = touchLocation 
    } 
} 

func resetImage(){ 

    drawArea.image = nil    
} 

}

+0

我试图使用修改后添加的代码,但绘制的线条不会保留,并在用户触摸后留下一小段痕迹 – Kawalski968

+0

您可以再次检查一次吗?因为相同的代码为我提供了结果。 – jegadeesh

+0

我再次检查,它仍然如我所述。我也在iPad上测试以确保。奇怪的是它对你有用。为了进一步隔离问题,我在一个完全空白的视图控制器上测试了我的代码,其中imageview的大小与屏幕相同,并且工作得很完美。只有在UIView类中的imageview内部实现它时才会出现问题。我也减少了该视图控制器上的imageview的大小,它仍然按预期工作。 – Kawalski968

我终于得到了它的正常工作。我利用你的想法改为使用贝塞尔路径,并修改它以限制绘图范围到UIView。

class DrawView: UIView { 
var drawArea: UIImageView! 
var clearDrawArea: UIButton! 
var lastTouch = CGPoint.zero 
var context: CGContext! 
var path: UIBezierPath! 
init(){ 
    context = UIGraphicsGetCurrentContext() 
    path = UIBezierPath() 
    super.init(frame: CGRect(x: UIScreen.main.bounds.width*0.135, y:UIScreen.main.bounds.height*0.05, width: UIScreen.main.bounds.width*0.8, height: UIScreen.main.bounds.height*0.9)) 
    drawArea = UIImageView(frame: CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: self.bounds.width*0.9, height: self.bounds.height*0.86)) 
    drawArea.backgroundColor = UIColor.white 

    let buttonWidth = self.bounds.width*0.2 
    let buttonHeight = self.bounds.height*0.1 
    clearDrawArea = UIButton(frame: CGRect(x: (self.bounds.width*0.61)-(buttonWidth/2), y: self.bounds.height*0.94, width: buttonWidth, height: buttonHeight)) 
    clearDrawArea.setTitle("Clear Draw Area", for: .normal) 
    clearDrawArea.backgroundColor = UIColor(red: 49/255, green: 200/255, blue: 134/255, alpha: 255) 
    clearDrawArea.addTarget(self, action: #selector(resetImage), for: .touchUpInside) 

    self.addSubview(clearDrawArea) 
    self.addSubview(drawArea) 

} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

    if let firstTouch = touches.first{ 

     lastTouch = firstTouch.location(in: drawArea) 
    } 

} 
func drawLines(_ from: CGPoint, to: CGPoint){ 
    UIGraphicsBeginImageContext(drawArea.frame.size) 

    path.move(to: CGPoint(x: from.x, y: from.y)) 
    path.addLine(to: CGPoint(x: to.x, y: to.y)) 

    UIColor.black.setStroke() 
    path.lineWidth = 3 
    path.stroke() 

    context?.saveGState() 
    context?.addPath(path.cgPath) 
    context?.closePath() 
    context?.restoreGState() 

    drawArea.image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
} 
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 


    if let firstTouch = touches.first { 
     let touchLocation = firstTouch.location(in: drawArea) 
     drawLines(lastTouch, to: touchLocation) 

     lastTouch = touchLocation 
    } 
} 

func resetImage(){ 
    path.removeAllPoints() 
    drawArea.image = nil    
} 

}

我也有这个问题。我通过修改约束来修复它,以便将视图固定到视图控制器。我本来有一个长宽比,这是在6/7尺寸,而不是5/SE尺寸或PLUS尺寸导致这个问题。这可能是为什么通过测试代码提交另一个答案,它为他们工作,但不适合你。如果uiView和图形区域没有对齐并且大小合适,它会扭曲你的绘图/原因'条纹',这些大条纹似乎来自任何地方/只绘制某些区域/你会在一个地方触及,并且会画出某处其他。

我建议测试所有屏幕尺寸以确保您的功能在所有屏幕上都能正常工作,并且使用您的约束设置看起来正确。