๊ธ€ ์ž‘์„ฑ์ž: ๊ฐœ๋ฐœํ•˜๋Š” ํ›ˆ์ด

UIPanGestureRecognizer

UIPanGestureRecognizer๋Š” GestureRecognizer์˜ ์„œ๋ธŒํด๋ž˜์Šค ์ค‘ ํ•˜๋‚˜๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์„ ํƒญ ํ•˜๊ณ  ์›€์ง์ด๋Š” ๋™์ž‘์„ ์ธ์‹ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. UIPanGestureRecognizer์˜ ๋ฉ”์„œ๋“œ๋Š” translation(์›€์ง์ž„)๊ณผ velocity(์†๋„)๋ฅผ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ UIPanGestureRecognizer๋ฅผ ํ†ตํ•ด์„œ ์•„๋ž˜ ๋ณด์ด๋Š” ๋™๊ทธ๋ž€ ์›์„ ๋‹ค๋ฅธ ์œ„์น˜๋กœ ์›€์ง์ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

 

UIPanGestureRecognizer ์ถ”๊ฐ€ํ•˜๊ธฐ

์Šคํ† ๋ฆฌ๋ณด๋“œ๋กœ ์ถ”๊ฐ€ํ•˜๊ธฐ 

์Šคํ† ๋ฆฌ ๋ณด๋“œ๋กœ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” ํ•ญ์ƒ ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์Šคํ† ๋ฆฌ๋ณด๋“œ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ PanGestureRecognizer๋ฅผ ์„ ํƒํ•˜๊ณ , 

 

์ œ์Šค์ฒ˜ ์ธ์‹๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ทฐ์— ๋Œ์–ด๋†“์œผ๋ฉด ์ธ์‹๊ธฐ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ œ์Šค์ฒ˜๊ฐ€ ์ž˜ ์ธ์‹๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•˜๋‹จ์— ๋ ˆ์ด๋ธ”์„ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•˜๊ณ  ๋“œ๋ž˜๊ทธ๊ฐ€ ์ธ์‹๋˜๋ฉด ์ƒํƒœ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var statusLabel: UILabel!
    @IBOutlet weak var targetCircle: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func panGestureHandler(_ sender: Any) {
        self.statusLabel.text = "Recognized"
    }
}

์ฝ”๋“œ๋กœ ์ถ”๊ฐ€ํ•˜๊ธฐ

์ฝ”๋“œ๋กœ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” UIPanGestureRecognizer ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ ๋’ค, ์›ํ•˜๋Š” ๋ทฐ์— ์ถ”๊ฐ€ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var targetCircle: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureHandler))
        self.targetCircle.addGestureRecognizer(panGestureRecognizer)
    }
    
    @objc func panGestureHandler(sender: UIPanGestureRecognizer) {
        print("pan gesture recognized")
    }
}

action ์ธ์ž์—๋Š” ์ œ์Šค์ฒ˜๊ฐ€ ์ธ์‹๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰ํ•˜๊ณ ์ž ํ•˜๋Š” ๋™์ž‘๋“ค์„ ๋ฉ”์„œ๋“œ๋กœ ์ •์˜ํ•ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ์š”, ์Šคํ† ๋ฆฌ ๋ณด๋“œ์—์„œ ์ถ”๊ฐ€ํ–ˆ์„ ๋•Œ์˜ IBAction๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์œ„์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์›ํ•˜๋Š” ์˜์—ญ์„ ๋“œ๋ž˜๊ทธํ–ˆ์„ ๋•Œ๋งŒ ์ œ์Šค์ฒ˜ ์ธ์‹์ด ๋™์ผํ•˜๊ฒŒ ์ž˜ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

UIPanGestureRecognizer๊ฐ€ ์•Œ๋ ค์ฃผ๋Š” ์ •๋ณด 1: ์ƒํƒœ

UIPanGesutreRecognizer๋Š” ๋‹ค๋ฅธ GestureRecognizer๋“ค์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž์˜ ์ œ์Šค์ฒ˜ ์ƒํƒœ๋ฅผ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. GestureRecognizer์˜ ์ƒํƒœ์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋Š” ๋‹ค๋ฅธ ํฌ์ŠคํŠธ์—์„œ ๋” ์ž์„ธํžˆ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

UIPanGestureRecognizer์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ƒํƒœ๋Š” Began, Changed, Ended์ž…๋‹ˆ๋‹ค. Began์€ ์ œ์Šค์ฒ˜ ์ธ์‹๊ธฐ๊ฐ€ ์‚ฌ์šฉ์ž์˜ ์ œ์Šค์ฒ˜๋ฅผ ์ธ์‹ํ•˜์—ฌ ๋“œ๋ž˜๊ทธ๊ฐ€ ์‹œ์ž‘ํ–ˆ์Œ์„ ์˜๋ฏธํ•˜๊ณ , Changed๋Š” ๋“œ๋ž˜๊ทธ๊ฐ€ ๊ณ„์†๋˜์–ด ์œ„์น˜๊ฐ€ ๋ณ€ํ™”๋จ์„, ๊ทธ๋ฆฌ๊ณ  Ended๋Š” ์‚ฌ์šฉ์ž์˜ ์˜๋„๋Œ€๋กœ(์˜๋„ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•Œ๋ฆผ์ด ๋œฌ๋‹ค๋˜์ง€, ์ „ํ™”๊ฐ€ ์˜จ๋‹ค๋˜์ง€..) ์†๊ฐ€๋ฝ์„ ํ™”๋ฉด์—์„œ ๋–ผ์–ด์„œ ๋“œ๋ž˜๊น…์ด ์ข…๋ฃŒ๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. 

 

๊ทธ๋Ÿผ ํ•˜๋‹จ ๋ ˆ์ด๋ธ”์— ์ƒํƒœ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋„๋ก ํ•ด๋ณผ๊นŒ์š”?

    @IBAction func panGestureHandler(_ sender: UIPanGestureRecognizer) {
        switch sender.state {
        case .possible:
            self.statusLabel.text = "Possible"
        case .began:
            self.statusLabel.text = "Began"
        case .changed:
            self.statusLabel.text = "Changed"
        case .cancelled:
            self.statusLabel.text = "Cancelled"
        case .ended:
            self.statusLabel.text = "Ended"
        case .failed:
            self.statusLabel.text = "Failed"
        }
    }

์ด๋ ‡๊ฒŒ ์ œ์Šค์ฒ˜ ์ธ์‹๊ธฐ๊ฐ€ ๋™์ž‘ํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ ์ƒํƒœ๋ฅผ ๋ ˆ์ด๋ธ”์— ๋‚˜ํƒ€๋‚ด๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•˜๋ฉด

 

๋น ๋ฅด๊ฒŒ Begin์„ ๊ฑฐ์ณ Changed ๊ฐ€ ๋˜์—ˆ๋‹ค๊ฐ€ ๋“œ๋ž˜๊ทธ๋ฅผ ์ค‘๋‹จํ•˜๋ฉด Ended ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ ์ œ์Šค์ฒ˜๊ฐ€ ์ฒ˜์Œ ์ธ์‹๋˜์—ˆ์„ ๋•Œ ์–ด๋–ค ์ž‘์—…์„ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด Began ์ƒํƒœ์— ํ•ด๋‹น ๋กœ์ง์„ ์ž‘์„ฑํ•˜๊ณ , ์ œ์Šค์ฒ˜๊ฐ€ ๋๋‚ฌ์„ ๋•Œ ์–ด๋–ค ์ž‘์—…์„ ์ง€์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด Ended ์ƒํƒœ์— ๋กœ์ง์„ ์ž‘์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 

 

UIPanGestureRecognizer๊ฐ€ ์•Œ๋ ค์ฃผ๋Š” ์ •๋ณด 2: Translation 

๋„์ž…๋ถ€์—์„œ ์„ค๋ช…ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ UIPanGestureRecognizer๋Š” Translation ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

translation(in:)
Interprets the pan gesture in the coordinate system of the specified view.

Declaration
func translation(in view: UIView?) -> CGPoint

Parameters
view
The view in whose coordinate system the translation of the pan gesture should be computed. If you want to adjust a view's location to keep it under the user's finger, request the translation in that view's superview's coordinate system.

Return Value
A point identifying the new location of a view in the coordinate system of its designated superview.

๊ณต์‹ ๋ฌธ์„œ์˜ ์„ค๋ช…์„ ๋ณด๋ฉด ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์‰ฌ์šด๋ฐ์š”, ์ธ์ž๋กœ ์ „๋‹ฌ๋˜๋Š” ๋ทฐ์˜ ์ขŒํ‘œ๊ณ„์— ๋”ฐ๋ผ์„œ ์ฒ˜์Œ ์ œ์Šค์ฒ˜๊ฐ€ ์ธ์‹๋˜์—ˆ์„ ๋•Œ๋ถ€ํ„ฐ ์–ผ๋งˆ๋‚˜ ์ขŒํ‘œ๊ฐ€ ์ด๋™๋˜์—ˆ๋Š”์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋™๊ทธ๋ผ๋ฏธ ๋ทฐ์— ์ œ์Šค์ฒ˜๋ฅผ ๋‹ฌ์•˜์œผ๋‹ˆ ๊ทธ ์ƒ์œ„ ๋ทฐ๋ฅผ ์ธ์ž๋กœ ๋„˜๊ฒจ์„œ ์ขŒํ‘œ๋ฅผ ์–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

 

์ด๊ฒƒ๋„ ํ•˜๋‹จ ๋ ˆ์ด๋ธ”์— ํ‘œ์‹œํ•ด์„œ ๋ณ€ํ™”๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ณผ๊ฒŒ์š”. 

@IBAction func panGestureHandler(_ sender: UIPanGestureRecognizer) {
    self.statusLabel.text = "\(sender.translation(in: self.view).x.rounded()) \(sender.translation(in: self.view).y.rounded())"
}

์†Œ์ˆ˜์ ์ด ๋‚˜์˜ค๋ฉด ๋ณด๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ์–ด๋ ค์šธ ๊ฒƒ ๊ฐ™์•„์„œ translation์˜ ๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜๋œ ์ขŒํ‘œ์˜ X์™€ Y๋ฅผ ๋ฐ˜์˜ฌ๋ฆผํ•ด์„œ ๋ ˆ์ด๋ธ”์— ํ‘œ์‹œํ•˜๋„๋ก ํ•ด๋ดค์Šต๋‹ˆ๋‹ค. 

 

์ด๋ ‡๊ฒŒ ๋“œ๋ž˜๊ทธํ•˜๋ฉด์„œ ์ด๋™ํ•œ ์ขŒํ‘œ๊ฐ€ ์ฒ˜์Œ ๋“œ๋ž˜๊ทธ๋ฅผ ์‹œ์ž‘ํ•œ ์ง€์ ์œผ๋กœ๋ถ€ํ„ฐ ์–ผ๋งˆ๋‚˜ ๋–จ์–ด์ ธ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์›์„ ์ด๋™์‹œํ‚ค๊ณ ์ž ํ•˜๋‹ˆ๊นŒ ์ด ์ขŒํ‘œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์›์„ ๊ณ„์† ์›€์ง์—ฌ์ฃผ๋ฉด ๋  ๊ฒƒ ๊ฐ™๋„ค์š”. ์ด๊ฑธ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค!

@IBAction func panGestureHandler(_ sender: UIPanGestureRecognizer) {
        let translation = sender.translation(in: self.view)
        self.targetCircle.center.x += translation.x
        self.targetCircle.center.y += translation.y
}

์‹คํ–‰ํ•ด๋ณผ๊นŒ์š”?

 

ํ„ฐ์น˜๋ฅผ ์›€์ง์ด๋Š”๋Œ€๋กœ ๋ทฐ๊ฐ€ ์ด๋™ํ•  ๊ฒƒ์„ ๊ธฐ๋Œ€ํ–ˆ์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.. ๋ฐ”๋กœ ์ฝ”๋“œ์—์„œ ๋งˆ์ง€๋ง‰ ํ•œ ์ค„์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ์šฐ๋ฆฌ๋Š” setTranslation() ๋ฉ”์„œ๋“œ์˜ ํ˜ธ์ถœ์„ ๋งˆ์ง€๋ง‰์— ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    @IBAction func panGestureHandler(_ sender: UIPanGestureRecognizer) {
        let translation = sender.translation(in: self.view)
        self.targetCircle.center.x += translation.x
        self.targetCircle.center.y += translation.y
        sender.setTranslation(CGPoint.zero, in: targetCircle)
    }

์ด๋ ‡๊ฒŒ ํ•œ ์ค„์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ณด๋ฉด!

 

์›ํ•˜๋Š” ๋Œ€๋กœ ์ž˜ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๊ทธ๋Ÿผ setTranslation์ด ์–ด๋–ค ์—ญํ• ์„ ํ•ด์ฃผ๋Š” ๊ฑธ๊นŒ์š”? ์• ํ”Œ ๋ฌธ์„œ์—๋„ ๋ช…์พŒํ•œ ํ•ด๋‹ต์ด ๋‚˜์˜ค์ง€ ์•Š์•„์„œ ๊ตฌ๊ธ€๋ง์„ ํ•˜๋˜ ์ค‘์— ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์˜ ์ข‹์€ ๋‹ต๋ณ€์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

 

https://stackoverflow.com/questions/29558622/pan-gesture-why-need-settranslation-to-zero

 

Pan gesture: why need setTranslation to zero?

I add a pan gesture to a view, move the view while finger moved, but I found if I do not call recognizer.setTranslation(CGPointZero, inView: self.view), translation is not right. why ? @IBAction...

stackoverflow.com

 

๋‹ต๋ณ€์˜ ํ•ต์‹ฌ์ ์ธ ๋‚ด์šฉ์€ "UIPanGestureRecognizer๋Š” ๋ทฐ๊ฐ€ ์ด๋™ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ•œ๋‹ค"์ž…๋‹ˆ๋‹ค. ์œ„์—์„œ translation ๋ฉ”์„œ๋“œ๊ฐ€ ๋“œ๋ž˜๊ทธ๊ฐ€ ์ฒ˜์Œ ์‹œ์ž‘๋œ ์ง€์ ์œผ๋กœ๋ถ€ํ„ฐ์˜ ์ด๋™์ขŒํ‘œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๋ทฐ๋ฅผ ์ด๋™์‹œ์ผฐ๊ธฐ ๋•Œ๋ฌธ์— ๋“œ๋ž˜๊ทธ๊ฐ€ ์ฒ˜์Œ ์‹œ์ž‘๋œ ์ง€์ ์˜ ์ขŒํ‘œ๋Š” ๋” ์ด์ƒ ๋ทฐ์˜ ์ขŒํ‘œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. UIPanGestureRecognizer๋Š” ์ด ์‚ฌ์‹ค์„ ์•Œ์ง€ ๋ชปํ•˜๊ณ  ๊ณ„์†ํ•ด์„œ ํ•ด๋‹น ์ง€์ ์œผ๋กœ๋ถ€ํ„ฐ์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ทฐ๊ฐ€ ์ด์ƒํ•œ ์œ„์น˜๋กœ ์ด๋™ํ–ˆ๋˜ ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ๋งˆ์ง€๋ง‰์— setTranslation ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ translation ๋ฉ”์„œ๋“œ๊ฐ€ ๊ณ„์‚ฐํ•  ๊ธฐ์ค€ ์ขŒํ‘œ๋ฅผ ํ˜„์žฌ ๋ทฐ์˜ ์ขŒํ‘œ๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” ๊ฒƒ์œผ๋กœ ๋“œ๋ž˜๊ทธ์˜ ์‹œ์ž‘์ ์„ ๊ณ„์†ํ•ด์„œ ์—…๋ฐ์ดํŠธํ•ด์ฃผ์–ด์•ผ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋“œ๋ž˜๊ทธ์˜ ๋™์ž‘์ด ์ˆ˜ํ–‰๋˜์—ˆ๋˜ ๊ฒƒ์ด์ฃ .

 

UIPanGestureRecognizer๊ฐ€ ์•Œ๋ ค์ฃผ๋Š” ์ •๋ณด 2: Velocity

๋งˆ์ง€๋ง‰์œผ๋กœ velocity์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! velocity() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, ๊ทธ ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ๋Š” ์†๋„๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์†๋„๋Š” "points per second"๋กœ ํ‘œํ˜„๋œ๋‹ค๊ณ  ๊ณต์‹๋ฌธ์„œ์— ๋‚˜์™€์žˆ๋„ค์š”. ์ดˆ ๋‹น ์›€์ง์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค! ์†๋„ ๊ฐ’์€ horizontal, vertical๋กœ ๋ถ„๋ฆฌ๋˜์–ด์„œ ์–ป์„ ์ˆ˜ ์žˆ๊ณ  ์ด๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด x, y ์ขŒํ‘œ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” CGPoint๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด์ฃ !

 

์ด ๊ฐ’์„ ์ด์šฉํ•ด์„œ ์šฐ๋ฆฌ๋Š” ์–ด๋–ค ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ์š”? ๋ฐ”๋กœ ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค!  x, y์˜ ์Œ/์–‘์— ๋”ฐ๋ผ ์šฐ๋ฆฌ๋Š” ๋ฐฉํ–ฅ์„ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ํ…Œ์ŠคํŠธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

        let velocity = sender.velocity(in: self.targetCircle)
        let x = velocity.x
        let y = velocity.y
        
        switch (x, y) {
        case _ where x == 0.0 && y < 0.0:
            self.statusLabel.text = "โฌ†๏ธ"
        case _ where x > 0.0 && y < 0.0:
            self.statusLabel.text = "โ†—๏ธ"
        case _ where x > 0.0 && y == 0.0:
            self.statusLabel.text = "โžก๏ธ"
        case _ where x > 0.0 && y > 0.0:
            self.statusLabel.text = "โ†˜๏ธ"
        case _ where x == 0.0 && y > 0.0:
            self.statusLabel.text = "โฌ‡๏ธ"
        case _ where x < 0.0 && y > 0.0:
            self.statusLabel.text = "โ†™๏ธ"
        case _ where x < 0.0 && y == 0.0:
            self.statusLabel.text = "โฌ…๏ธ"
        case _ where x < 0.0 && y < 0.0:
            self.statusLabel.text = "โ†–๏ธ"
        default:
            self.statusLabel.text = "๋ฐฉํ–ฅ์€?"
        }

์ด 8 ๋ฐฉํ–ฅ์„ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. x ์ถ•์€ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™ํ•  ๋•Œ ์–‘์ˆ˜, ์™ผ์ชฝ์œผ๋กœ ์ด๋™ํ•  ๋•Œ ์Œ์ˆ˜๊ฐ€ ๋˜๊ณ , y์ถ•์€ ์œ„๋กœ ์ด๋™ํ•  ๋•Œ ์Œ์ˆ˜, ์•„๋ž˜๋กœ ์ด๋™ํ•  ๋•Œ ์–‘์ˆ˜๊ฐ€ ๋จ์„ ์ด์šฉํ•˜๋ฉด ๋Œ€๊ฐ์„ ๊นŒ์ง€ ๋ชจ๋‘ 8๊ฐœ์˜ ๋ฐฉํ–ฅ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐฉํ–ฅ์ด ์ž˜ ํ™•์ธ๋˜๋„ค์š”~! ์ด๋ ‡๊ฒŒ ๋ฐฉํ–ฅ์„ ํ™•์ธํ•˜๋Š” ์šฉ๋„๋กœ Velocity๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค!

 

 

์ „์ฒด ์˜ˆ์ œ ์ฝ”๋“œ 

@IBAction func panGestureHandler(_ sender: UIPanGestureRecognizer) {
        
        // ์ƒํƒœ ํ™•์ธ
        switch sender.state {
        case .began:
            print("Began")
        case .changed:
            print("Changed")
        case .ended:
            print("Ended")
        default:
            break
        }
        
        // ๋ทฐ ์ด๋™
        let translation = sender.translation(in: self.view)
        self.targetCircle.center.x += translation.x
        self.targetCircle.center.y += translation.y
            
        // ๋ฐฉํ–ฅ ํ™•์ธ
        let velocity = sender.velocity(in: self.targetCircle)
        let x = velocity.x
        let y = velocity.y
        
        switch (x, y) {
        case _ where x == 0.0 && y < 0.0:
            self.statusLabel.text = "โฌ†๏ธ"
        case _ where x > 0.0 && y < 0.0:
            self.statusLabel.text = "โ†—๏ธ"
        case _ where x > 0.0 && y == 0.0:
            self.statusLabel.text = "โžก๏ธ"
        case _ where x > 0.0 && y > 0.0:
            self.statusLabel.text = "โ†˜๏ธ"
        case _ where x == 0.0 && y > 0.0:
            self.statusLabel.text = "โฌ‡๏ธ"
        case _ where x < 0.0 && y > 0.0:
            self.statusLabel.text = "โ†™๏ธ"
        case _ where x < 0.0 && y == 0.0:
            self.statusLabel.text = "โฌ…๏ธ"
        case _ where x < 0.0 && y < 0.0:
            self.statusLabel.text = "โ†–๏ธ"
        default:
            self.statusLabel.text = "๋ฐฉํ–ฅ์€?"
        }
        
        sender.setTranslation(CGPoint.zero, in: targetCircle)
    }

 

์—ฌ๊ธฐ๊นŒ์ง€ UIPanGesture์˜ ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ๋ฐฉ๋ฒ•๋“ค์„ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค! ์ž˜๋ชป๋œ ๋‚ด์šฉ์ด ์žˆ๊ฑฐ๋‚˜ ๊ต์ •์ด ํ•„์š”ํ•œ ๋‚ด์šฉ์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€ ์ฃผ์„ธ์š” ์˜ค๋Š˜๋„ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค๐ŸŽ