티스토리 뷰

이번 포스팅은 사용자의 탭과 터치 동작을 받아서 처리하는 방법과 이를 이용하여 간단한 스케치 어플을 만들어 보려고 한다. 

 

터치의 경우 View Controller에서 오버라이드 메서드를 제공하기 때문에 구현하기 아주 쉬운 이벤트이다.

 

바로 한번 들어가보도록 하자.


우선, Navigation Controller를 사용하여 2개의 View를 갖도록 할 것이다. 

 

첫번째 뷰는 터치와 탭, 드래그와 같은 동작에 대한 이벤트를 처리하고 터치, 탭 카운트를 표시해주는 간단한 터치 View로 구성하고, 

두번째 뷰는 간단하게 image view 위에 스케치를 할 수 있도록 구현한 스케치 View로 구성한다.

 

스토리보드는 각각 다음과 같다.

 

◎ ViewController

제약 조건은 아래와 같다.

 

◎DrawViewController


코드 또한 기능이 몇개 없기 때문에 굉장히 간단한데, 자세한 설명은 포스팅이 길어지는 게 싫어서 주석으로 적어 놓았다.

 

◎ ViewController

import UIKit

class ViewController: UIViewController {

    @IBOutlet var txtMessage: UILabel!
    @IBOutlet var txtTapCount: UILabel!
    @IBOutlet var txtTouchCount: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    // 터치가 시작될 떄 호출된다.
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first! as UITouch
        txtMessage.text = "Touches Began"
        txtTapCount.text = String(touch.tapCount)
        txtTouchCount.text = String(touches.count)
    }
    
    // 터치된 손가락이 움직였을 때 호출된다.
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first! as UITouch
        
        txtMessage.text = "Touches Moved"
        txtTapCount.text = String(touch.tapCount)
        txtTouchCount.text = String(touches.count)
    }
    
    // 화면에서 손가락을 떼었을 때 호출된다.
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first! as UITouch
        
        txtMessage.text = "Touches Ended"
        txtTapCount.text = String(touch.tapCount)
        txtTouchCount.text = String(touches.count)
    }


}

 

◎DrawViewController

import UIKit

class DrawViewController: UIViewController {

    @IBOutlet var imgView: 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 btnClear(_ sender: UIButton) {
        imgView.image = nil
    }
    
    // 터치가 시작될 떄 호출된다.
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first! as UITouch
        
        // 터치된 위치를 lastPoint에 저장
        lastPoint = touch.location(in: imgView)
    }
    
    // 터치된 손가락이 움직였을 때 호출된다.
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        UIGraphicsBeginImageContext(imgView.frame.size)
        
        // 라인의 색상, 펜 끝, 사이즈 설정
        UIGraphicsGetCurrentContext()?.setStrokeColor(lineColor)
        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round)
        UIGraphicsGetCurrentContext()?.setLineWidth(lineSize)
        
        // 라인의 끝 모양을 라운드를 설정
        let touch = touches.first! as UITouch
        
        // 터치된 위치를 currPoint로 가지고 온다
        let currPoint = touch.location(in: imgView)
        
        // 현재 image View에 있는 이미지를 Image view 크기로 그림을 그린다.
        imgView.image?.draw(in: CGRect(x: 0, y: 0, width: imgView.frame.size.width, height: imgView.frame.size.height))
        
        // 이전에 이동된 위치인 last point로 시작 위치를 이동시킨다
        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
       
        // lastPoint에서 현재 위치에서 currPoint까지 선을 추가한다
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: currPoint.x, y: currPoint.y))
        
        // 추가한 선을 Context에 그림
        UIGraphicsGetCurrentContext()?.strokePath()
        
        // image view 에 Context 추가
        imgView.image = UIGraphicsGetImageFromCurrentImageContext()
        
        // UIGraphics 종료
        UIGraphicsEndImageContext()
        
        lastPoint = currPoint
    }
    
    // 화면에서 손가락을 떼었을 때 호출된다.
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        UIGraphicsBeginImageContext(imgView.frame.size)
        
        // 라인의 색상, 펜 끝, 사이즈 설정
        UIGraphicsGetCurrentContext()?.setStrokeColor(lineColor)
        UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round)
        UIGraphicsGetCurrentContext()?.setLineWidth(lineSize)
        
        // 현재 image View에 있는 이미지를 Image view 크기로 그림을 그린다.
        imgView.image?.draw(in: CGRect(x: 0, y: 0, width: imgView.frame.size.width, height: imgView.frame.size.height))
        
        // 이전에 이동된 위치인 last point로 시작 위치를 이동시킨다
        UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
       
        // lastPoint에서 현재 위치에서 lastPoint까지 선을 추가한다
        UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
        
        // 추가한 선을 Context에 그림
        UIGraphicsGetCurrentContext()?.strokePath()
        
        // image view 에 Context 추가
        imgView.image = UIGraphicsGetImageFromCurrentImageContext()
        
        // UIGraphics 종료
        UIGraphicsEndImageContext()
    }
    
    // 휴대폰을 흔들었을 때, 이미지 삭제
    override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            imgView.image = nil
        }
    }
}

 

 

끝!!

반응형
Comments