일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Greedy
- Node.js
- 알고리즘
- mysql
- 풀이
- Swift
- Docker
- ios
- 실버쥐
- 플로이드와샬
- 백준
- 그래프
- Stack
- 부르트포스
- dp
- 캡스톤정리
- DeepLearning
- 백트래킹
- BFS
- Blockchain
- NeuralNetwork
- 탐색
- ReLU
- sigmoid
- 프로그래머스
- C++
- Algorithm
- 그리디
- dfs
- 문제풀이
- Today
- Total
개발아 담하자
[iOS/Swift] CanvasView 를 사용해 그림 그리기 본문
Canvas View 위에 그림을 그려보자!
참고 강의 자료 : LBTA Youtube
https://www.youtube.com/watch?v=E2NTCmEsdSE&t=1s
1. 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?) {
...
}
}
CanvasView 의 세 가지 메소드 draw(), touchesBegan(), touchesMoved() 를 사용할 것이다.
touchesBegan() 은 터치가 처음 인식될 때 호출되는 메소드이다.
touchesMoved() 는 터치가 처음 이루어지고 움직일 때 마다 호출되는 메소드이다.
override func loadView(){
self.view = canvas
}
override func viewDidLoad() {
super.viewDidLoad()
canvas.backgroundColor = .white
}
CanvasView 를 만든 후 loadview 에 추가해준다.
loadview란 ?
ViewController.view 를 생성하는 곳이다. (아직 self.view 가 만들어지지 않음)
viewDidLoad 에 작성한다면 아래와 동일하다.
override func viewDidLoad(){
view.addSubview(canvas)
canvas.frame = view.frame
}
2. Line Model
struct Line {
let storkeWidth: Float
let color: UIColor
var points: [CGPoint]
}
var lines = [Line]()
Line 구조체는 stokeWidth, color points[] 정보를 가지고 있다.
각각 정보는 선의 굵기, 색깔, 위치 정보를 나타낸다.
3. Draw Line
3-1. touchesBegan()
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
lines.append(Line.init(storkeWidth: strokeWidth, color: strokeColor, points: []))
}
touchesBegan 은 첫 터치할 때 호출되는 메소드이다.
lines 에 line 을 append 해준다. (위치정보 points 는 빈 배열이다.)
3-2. 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 가 변했다는 사실을 시스템에 알려준다.
3-3. draw()
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()을 사용해 라인을 그려준다.
4. Undo & Clear
func undo(){
_ = lines.popLast()
setNeedsDisplay()
}
func clear(){
lines.removeAll()
setNeedsDisplay()
}
undo 는 선 한 개를 그리기 취소하고, clear 는 모든 정보를 초기화한다.
5. 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() 메소드에서 선을 그릴 때 원하는 색상과 굵기를 지정해준다.
이제 최종 완성 ‼️‼️
'📱 iOS' 카테고리의 다른 글
[iOS/Swift] Youtube Player 만들기 (썸네일 불러오기, 영상 재생하기) (1) | 2020.05.01 |
---|---|
[iOS/Swift] Core Data 를 사용한 todo list app 만들기 (0) | 2020.05.01 |
[iOS/Swift] LineChart 를 사용해 그래프 그리기 (2) | 2020.03.30 |
[iOS/SwiftUI] Animated Bar Chart 만들기 / Light mode, Dark mode 구분하기 (0) | 2020.03.22 |
[iOS/SwiftUI] SwiftUI 첫 실행하기 (0) | 2020.03.22 |