[iOS] Event & Gesture handling : PTS (Pinch-Touch&Tap-Sketch/Swipe) Sketch Example 2
2022. 8. 31. 17:56ㆍiOS/Learning
지난 포스팅에 이어서 Sketch View, Swipe View를 구현한다.
Set the Sketch View Layout
1. Library[➕]버튼을 클릭하여 Vertical Stack View 가져오기
2. Stack View 선택하고 하단의 Add New Constraints을 아래와 같이 세팅
3. Library[➕]버튼을 클릭하여 Button, Image View를 Stack View안에 추가
4. Button text: Clear로 변경, Add New Constraints 버튼 클릭하여 Heght: 40으로 변경
5. Outlet Variable & Action Function 추가
Editor 영역 상단 우측 Adjust Editor Options 버튼 > Assistant 클릭
Horizontal Stack View에서 값이 출력될 우측 Lable 3개 각각: Asisttant 코드 영역으로 Drag & Drop
Source Code
SketchViewController.swift
import UIKit
class SketchViewController: UIViewController {
@IBOutlet var canvas: UIImageView!
var lastPoint: CGPoint!
var lineSize: CGFloat = 2.0
var lineColor = UIColor.red.cgColor
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func clearCanvas(_ sender: UIButton) {
canvas.image = nil
}
// * 디바이스를 흔들었을때도 canvas를 clean
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
if motion == .motionShake {
canvas.image = nil
}
}
// * 사용자가 화면을 터치하면 스케치를 시작
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first! as UITouch // get the current touch event
lastPoint = touch.location(in: canvas)
}
// * 사용자가 터치한 손가락을 이동하면 스케치도 함께 이동
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
initalSketch()
let touch = touches.first! as UITouch
let currentPoint = touch.location(in: canvas)
drawLine(currentPoint: currentPoint)
lastPoint = currentPoint
}
// * 사용자가 화면에서 손가락을 떼면 스케치 끝
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
initalSketch()
drawLine(currentPoint: nil)
}
func initalSketch() {
UIGraphicsBeginImageContext(canvas.frame.size) // create a context for sketch
UIGraphicsGetCurrentContext()?.setStrokeColor(lineColor) // 라인 컬러
UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round) // 라인 끝모양 둥글게
UIGraphicsGetCurrentContext()?.setLineWidth(lineSize) // 라인 두께
}
func drawLine(currentPoint: CGPoint?) {
// 현재 canvas에 있는 이미지를 canvas의 크기로 그리기
canvas.image?.draw(in: CGRect(x: 0, y: 0, width: canvas.frame.size.width, height: canvas.frame.size.width))
// 이전에 이동된 위치인 lastPoint로 시작 위치 이동
UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
// lastPoint에서 currentPoint/lastPoint(현재 위치)까지 선 추가
if let currentPoint = currentPoint {
UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: currentPoint.x, y: currentPoint.y))
} else {
UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
}
UIGraphicsGetCurrentContext()?.strokePath() // 추가한 선을 콘텍스트에 그림
canvas.image = UIGraphicsGetImageFromCurrentImageContext() // 현재 콘텍스트에 그려진 이미지를 canvas(Image View)에 할당
UIGraphicsEndImageContext()
}
}
Result
더보기
DEBUG

???????????? 왜이래 -> canvas이미지 뷰 전체 이미지 draw함수 파라미터의 CGRect초기화할때 height 값을 width로 잘못 전달했더니 저딴식으로 나옴
drawLine함수에서 canvas 설정 할때 오타나서 생긴 버그

canvas.image?.draw(in: CGRect(x: 0, y: 0, width: canvas.frame.size.width, height: canvas.frame.size.width))
⬇️
canvas.image?.draw(in: CGRect(x: 0, y: 0, width: canvas.frame.size.width, height: canvas.frame.size.height))
Reference
Do it! 스위프트로 아이폰 앱 만들기 입문 개정 4판, 이지스 퍼블리싱, 송호정, 이범근