SwiftUI 커스텀 제스처 인식기 구현

작성일 :

SwiftUI에서 커스텀 제스처 인식기 구현하기

SwiftUI는 iOS 앱 개발을 단순화하고 직관적으로 만들어 주는 다양한 기능을 제공합니다. 그 중 제스처 인식은 매우 중요한 기능 중 하나입니다. 기본적으로 제공되는 제스처 말고도, 개발자가 직접 커스텀 제스처 인식기를 구현할 수 있습니다. 이 글에서는 SwiftUI에서 커스텀 제스처 인식기를 구현하는 방법에 대해 알아보겠습니다.

기본 제스처 이해하기

SwiftUI는 몇 가지 기본적인 제스처를 제공합니다. 탭, 스와이프, 드래그, 롱 프레스 등이 여기에 포함됩니다. 예를 들어, 탭 제스처는 다음과 같이 구현할 수 있습니다.

swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .onTapGesture {
                print("Text tapped!")
            }
    }
}

위의 코드는 간단한 탭 인식기를 Text에 추가합니다. 사용자가 텍스트를 탭하면 해당 이벤트가 콘솔에 Text tapped! 라는 메시지를 출력합니다. 하지만 경우에 따라, 기본 제스처 인식기만으로는 충분하지 않은 경우가 생길 수 있습니다. 그래서 우리는 커스텀 제스처 인식기를 만드는 방법을 알아봐야 합니다.

커스텀 제스처 인식기의 필요성

애플리케이션이 더 복잡해지면서, 확장된 제스처 인식기가 필요할 때가 있습니다. 예를 들어, 특정한 패턴의 스와이프 또는 멀티 터치를 인식하는 기능이 필요할 수 있습니다. 이러한 경우, 우리는 기본 제스처 인식기를 넘어선 커스텀 제스처 인식기를 구현해야 합니다.

커스텀 제스처 인식기 구현하기

커스텀 제스처 인식기를 구현하기 위해서는 우선 UIGestureRecognizer를 사용해야 합니다. 여기에서는 간단한 예제로, 두 손가락으로 화면을 드래그하는 제스처를 인식하는 커스텀 제스처를 만들어 보겠습니다.

Step 1: Gesture Recognizer 클래스를 생성하기

먼저, 커스텀 제스처 인식기를 생성할 클래스를 만들어야 합니다. UIGestureRecognizer를 상속받는 클래스를 생성하고, 원하는 제스처를 정의합니다.

swift
import UIKit

class TwoFingerDragGestureRecognizer: UIGestureRecognizer {
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesBegan(touches, with: event)
        guard touches.count == 2 else {
            self.state = .failed
            return
        }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesMoved(touches, with: event)
        if self.state == .possible {
            self.state = .began
        } else {
            self.state = .changed
        }
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
        super.touchesEnded(touches, with: event)
        if self.state == .changed || self.state == .began {
            self.state = .ended
        }
    }
}

이 코드는 두 손가락으로 드래그 하는 제스처를 인식하는 인식기를 정의합니다. 처음 두 개의 터치를 인식하고, 터치가 움직이면 상태를 began 또는 changed로 업데이트합니다. 터치가 끝나면 상태를 ended로 설정합니다.

Step 2: SwiftUI와 연결하기

SwiftUI와 통합하려면, UIKit의 UIViewRepresentable 프로토콜을 사용하여 SwiftUI 뷰에 추가할 수 있는 방법을 찾아야 합니다. 다음은 이를 구현하는 방법입니다.

swift
import SwiftUI

struct TwoFingerDragView: UIViewRepresentable {
    
    class Coordinator: NSObject {
        
        @objc func handleGesture(_ gestureRecognizer: TwoFingerDragGestureRecognizer) {
            // 커스텀 제스처 로직
            print("Two-finger drag recognized")
        }
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }
    
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        let gestureRecognizer = TwoFingerDragGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleGesture(_:)))
        view.addGestureRecognizer(gestureRecognizer)
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {}
}

이 코드는 SwiftUI UIViewRepresentable 프로토콜을 구현하는 커스텀 뷰를 정의합니다. Coordinator 클래스 내에 제스처 인식 핸들러를 정의하고, UIView에 커스텀 제스처 인식기를 추가합니다.

Step 3: SwiftUI ContentView에서 사용하기

이제 TwoFingerDragView를 다른 SwiftUI 뷰에서 사용할 수 있습니다.

swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        TwoFingerDragView()
            .frame(width: 300, height: 300)
            .background(Color.blue)
    }
}

이 코드는 TwoFingerDragView를 ContentView 내에서 사용합니다. 사용자가 두 손가락으로 드래그하면, 제스처 인식기가 이를 인식하고 콘솔에 메시지를 출력합니다.

결론

SwiftUI에서 커스텀 제스처 인식기를 만드는 것은 쉽지 않지만, 기본 제스처 인식기를 넘어서 복잡한 제스처를 처리하려면 꼭 필요합니다. 이번 글에서는 두 손가락 드래그 인식기를 예제로 사용하여 커스텀 제스처 인식기를 만드는 방법을 알아보았습니다. 이를 통해 더 복잡하고 다양한 사용자 인터페이스를 구현할 수 있습니다.