[iOS] 특정 뷰의 터치 이벤트 막기

z-wook·2025년 2월 14일
0
post-thumbnail

채팅 UI를 만들면서 채팅창을 터치하면 키보드가 내려가도록 하고 싶었지만, 전송 버튼을 터치했을 때는 키보드가 내려가지 않도록 하고 싶었습니다.

그런데 채팅창을 터치할 때 UICollectionView의 이벤트가 발생하여, 특정 뷰(UIControl)의 터치 이벤트는 gestureRecognizer가 감지하지 않도록 처리하려고 했습니다.

import UIKit

extension UIViewController {
    func hideKeyBoardWhenTappedScreen() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapHandler))
        tapGesture.cancelsTouchesInView = false
        tapGesture.delegate = self
        view.addGestureRecognizer(tapGesture)
    }
    
    @objc func tapHandler() {
        view.endEditing(true)
    }
}

extension UIViewController: @retroactive UIGestureRecognizerDelegate {
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        // 버튼이나 특정 뷰에 대한 터치가 gestureRecognizer에 전달되지 않도록 설정
        if let view = touch.view, view is UIControl {
            return false
        }
        return true
    }
}

@retroactive의 역할

@retroactive는 타입이 정의된 모듈과 관계없이 프로토콜을 적용할 수 있도록 허용하는 속성입니다.

위의 코드에서 UIViewController는 UIKit 프레임워크에서 정의된 타입이며, 원래 UIGestureRecognizerDelegate 프로토콜을 직접 채택하지 않았습니다.
하지만 @retroactive를 사용하면, UIKit이 선언된 모듈과 상관없이 UIViewController가 UIGestureRecognizerDelegate 프로토콜을 구현할 수 있습니다.

따라서 외부 라이브러리에서 정의된 타입에도 새로운 프로토콜을 적용할 수 있는 유연성이 생깁니다.

profile
🍎 iOS Developer

0개의 댓글