2017-11-28 24 views
0

UIImageView에서 무언가를 그릴 수있는 응용 프로그램을 개발하려고합니다. 다음 코드가 있습니다.신속한 UIImageView 그리기

import UIKit 
class Line 
{ 
    var startPoint:CGPoint 
    var endPoint:CGPoint 

    init (start:CGPoint , end:CGPoint) 
    { 
     startPoint = start 
     endPoint = end 
    } 
} 


class AnnotationView: UIView { 

    static internal let nibName = "AnnotationView" 
    @IBOutlet weak var imageView: UIImageView! 
    var lines :[Line] = [] 
    var lastPoint:CGPoint! 


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     lastPoint = touches.first?.location(in: self) 
    } 

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
     if let touch = touches.first 
     { 
      let newPoint = touch.location(in:self) 
      lines.append(Line(start: lastPoint, end: newPoint)) 
      lastPoint = newPoint 
      self.setNeedsDisplay() 
     } 
    } 
    override func draw(_ rect: CGRect) { 
     if let context = UIGraphicsGetCurrentContext() 
     { 
      context.beginPath() 
      for line in lines 
      { 
       context.move(to: line.startPoint) 
       context.addLine(to: line.endPoint) 
      } 
      context.setLineCap(CGLineCap.round) 
      context.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1) 
      context.setLineWidth(5) 
      context.strokePath() 
     } 
    } 
} 

는 이제 위의 코드에서 난 내가 인터페이스 빌더에서 슈퍼 뷰의 전체 크기로 설정되어있는 UIImageView이 곳 AnnotationView 클래스는 UIView의에서 파생 있습니다. 이것은 UIImageView에서 일례를 그리기 원하는 간단한 그리기 응용 프로그램입니다. 이제 문제는 imageView.image가 nil이면 내 그림을 표시하고 imageView.image에 설정된 이미지가 있으면 도면을 표시하지 않는 것입니다. 이 imageView에 설정된 이미지 만 표시됩니다. 두 시나리오 모두에서 디버깅을 수행하여 모든 메소드가 호출됩니다. 분명히 내가 놓치고있는 것이있다. 아무도 나를 도울 수 있습니까? 내 그림을 UIImageView에서 설정 한 이미지 위에 표시하고 싶습니다. 감사 니나

답변

0

문제는 당신이 당신의 UIImageView 포함, 서브 뷰의 뒤에 배치 된 AnnotationView의 주요 계층에서 그리고있는 것입니다. 해결 방법은 그림을 sublayer에 추가하여 AnnotationView의 메인 레이어에 추가하는 것입니다.

draw() 메서드에서 직접 선을 그리는 대신 도면 오버레이에 별도의 레이어가 있어야합니다.

let drawingLayer = CAShapeLayer() 

을 그리고 다른 한 빨리보기는 스토리 보드/펜촉에서로드로이 층에게 모든 것을 상단에 계층을 만들 awakeFromNib()를 오버라이드 (override) : 당신의 AnnotationView이 속성을 추가 이제 만들 수

override func awakeFromNib() { 
    super.awakeFromNib() 
    layer.addSublayer(drawingLayer) 
} 

func updateDrawingOverlay() { 
    let path = CGMutablePath() 

    for line in lines { 
     path.move(to: line.startPoint) 
     path.addLine(to: line.endPoint) 
    } 

    drawingLayer.frame = imageView.frame 
    drawingLayer.path = path 
    drawingLayer.lineWidth = 5 
    drawingLayer.strokeColor = UIColor.black.cgColor 

    setNeedsDisplay() 
} 

은 당신의 코드를 삭제하는 기능 대신 setNeedsDisplay()를 호출하는 오버레이를 업데이트해야 할 때마다 호출 draw(_:) 방법은 이제 중복 되었기 때문에 전화를 touchesMoved(_: with:)에서 updateDrawingOverlay() 전화로 바꿉니다.


모든 것은 당신을 위해 다음과 같아야합니다

import UIKit 

class Line { 
    var startPoint:CGPoint 
    var endPoint:CGPoint 

    init (start:CGPoint , end:CGPoint) { 
     startPoint = start 
     endPoint = end 
    } 
} 


class AnnotationView: UIView { 
    static internal let nibName = "AnnotationView" 
    @IBOutlet weak var imageView: UIImageView! 

    var lines :[Line] = [] 
    var lastPoint:CGPoint! 
    let drawingLayer = CAShapeLayer() 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     layer.addSublayer(drawingLayer) 
    } 

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

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     lastPoint = touches.first?.location(in: self) 
    } 

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
     if let touch = touches.first 
     { 
      let newPoint = touch.location(in:self) 
      lines.append(Line(start: lastPoint, end: newPoint)) 
      lastPoint = newPoint 
      updateDrawingOverlay() 
     } 
    } 

    func updateDrawingOverlay() { 
     let path = CGMutablePath() 

     for line in lines { 
      path.move(to: line.startPoint) 
      path.addLine(to: line.endPoint) 
     } 

     drawingLayer.frame = imageView.frame 
     drawingLayer.path = path 
     drawingLayer.lineWidth = 5 
     drawingLayer.strokeColor = UIColor.black.cgColor 

     setNeedsDisplay() 
    } 
} 

이 트릭을 할해야, 내가 어떻게되는지 알려 주시기 바랍니다.

+0

답장을 보내 주셔서 감사합니다. 이미지의 유무에 관계없이 그림을 그려서는 안됩니다. – neena

+0

@neena 새 버전을 복사하여 붙여 넣으십시오. init (frame :)을 awakeFromNib() 오버레이를 추가하기 전에 이미지보기가로드되었는지 확인하십시오. 일했는지 여부를 알려주세요. – nshuman

+0

그게 효과가있다. 당신의 도움을 주셔서 감사합니다! – neena