- This topic has 1개 답변, 2명 참여, and was last updated 4 years, 8 months 전에 by 야곰.
-
글쓴이글
-
-
은지짱참가자
- 글작성 : 13
- 답글작성 : 7
Drawing with CanvasView 🎨
캔버스에 그림을 그려보자 ✍️
📌 Make CanvasView
class Canvas: UIView { override func draw(_ rect: CGRect){ ... } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { ... } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { ... } }
override func loadView(){ self.view = canvas } override func viewDidLoad() { super.viewDidLoad() canvas.backgroundColor = .white }
loadView
란??
loadView : viewController.view 를 생성하는 곳이다. (아직 self.view 가 만들어지지 않음)
viewDidLoad 에 작성한다면 아래와 동일하다.override func viewDidLoad(){ view.addSubview(canvas) canvas.frame = view.frame }
<br/>
📌 Line Model
struct Line { let storkeWidth: Float let color: UIColor var points: [CGPoint] }
var lines = [Line]()
Line 구조체는
stokeWidth
,color
points[]
정보를 가지고 있다.
각각 정보는 선의 굵기, 색깔, 위치 정보를 나타낸다.<br/>
📌 Draw Line
- touchesBegan
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { lines.append(Line.init(storkeWidth: strokeWidth, color: strokeColor, points: [])) }
touchesBegan
은 첫 터치할 때 호출되는 메소드이다.
lines
에line
을 append 해준다. (위치정보points
는 빈 배열이다.)- touchesMoved
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { guard let point = touches.first?.location(in: nil) else { return } guard var lastLine = lines.popLast() else { return } lastLine.points.append(point) lines.append(lastLine) setNeedsDisplay() }
touchesMoved
는 손가락의 움직임을 추적하는 메소드이다.
point
는 현재 터치 위치 정보를 나타낸다.
지금 선을 그리고 있는lastLine
의points
배열에point
를 append 한다.setNeedsDisplay()
란?
View 의 컨텐츠가 변하면 이 View 가 변했다는 사실을 시스템에 알려준다.
- Draw Line
override func draw(_ rect: CGRect) { super.draw(rect) guard let context = UIGraphicsGetCurrentContext() else { return } lines.forEach { (line) in ... for (i,p) in line.points.enumerated() { if i==0{ // first index context.move(to: p) } else { context.addLine(to: p) } } context.strokePath() } }
lines
를 foreach 로 돌며 line 을 그려준다.
i
는 index,p
는 point 를 의미한다.move()
와addLine()
을 사용해 라인을 그려준다.<br/>
📌 Undo & Clear
func undo(){ _ = lines.popLast() setNeedsDisplay() }
func clear(){ lines.removeAll() setNeedsDisplay() }
undo
는 선 한 개를 그리기 취소하고,clear
는 모든 정보를 초기화한다.<br/>
📌 Setting Color & Width
@objc fileprivate func handleColorChange(button: UIButton){ canvas.setStrokeColor(color: button.backgroundColor ?? .black) } @objc fileprivate func handleSliderChange(){ canvas.setStrokeWidth(width: slider.value) }
위 메소드를 색상 변경 버튼과 UISlider에 addTarget 시켜준다.
fileprivate
이란?
자체 정의 소스 파일에 대한 엔티티 사용을 제한한다.
해당 세부 정보가 전체 파일 내에서 사용 될 때 특정 기능의 구현 세부 정보를 숨길 수 있다. (같은 모듈 내에서도 같은 소스 파일 안에서만 사용이 가능하다.)fileprivate var strokeColor = UIColor.black fileprivate var strokeWidth: Float = 1 func setStrokeWidth(width: Float){ self.strokeWidth = width } func setStrokeColor(color: UIColor) { self.strokeColor = color }
전역 변수로 설정해둔
stokeColor
,strokeWidth
값을 update 해 준다.context.setStrokeColor(line.color.cgColor) context.setLineWidth(CGFloat(line.storkeWidth))
draw()
메소드에서 선을 그릴 때 원하는 색상과 굵기를 지정해준다.
이제 최종 완성 ‼️‼️<br/>
📌 screenshots
2020-04-12 오후 12:42 #6586 -
야곰키 마스터
- 글작성 : 37
- 답글작성 : 579
멋진 튜토리얼이네요! 좋아요!
아쉬운 점은 맨 마지막 스크린샷 이미지가 안보이네요 ㅠ_ㅠ의견 : 이 튜토리얼을 처음 따라하는 사람이라면 메서드를 어디에 작성해야 하는지 모를것 같아요. 맨 위의 코드의
Canvas
클래스의 코드가 닫혀있는데, 그 다음 코드부터 그냥 메서드만 써두니 그 메서드가Canvas
클래스 안에 작성해야 하는 것인지, 밖에다 해야하는 것인지 잘 모르겠습니다. 저도 처음에 띠용 했네요 ㅎㅎ질문 :
undo
메서드에서_ = lines.popLast()
라고 해줬는데_
의 의미는 무엇일까요? 꼭 그렇게 해주지 않고lines.popLast()
해주면 안될까요?2020-04-12 오후 3:58 #6603
-
-
글쓴이글
- 답변은 로그인 후 가능합니다.