개발/Swift

[Swift] Superview 의 tap gesture 적용시 sub view에 영향 안주기

덤벨로퍼 2022. 8. 19. 16:24

Modern Collection View 와 MVVM 패턴 가이드

 

[iOS] Swift Modern Collection View & MVVM 패턴 가이드 | 덤벨로퍼 - 인프런

덤벨로퍼 | MVVM 패턴과 Modern Collection View를 사용해 네트워킹을 구현하고, 다양하고 동적인 Collection View를 자유자재로 다룰 수 있게 됩니다., Swift iOS UI, 제대로 다루는 핵심 기술! 📲 iOS Swift 레이

www.inflearn.com

 

Superview 의 tap gesture sub view에 영향 안주기

private func setDismissKeyboardEvent() {
        let gesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        self.view.addGestureRecognizer(gesture)
    }

위와 같이 superview에 tap제스쳐를 먹인 상황에서는

superview 안에있는 버튼이나 다른 view 들의 제스쳐가 인식이 안되는 경우가있다.

이를 해결하기 위해 따로 처리해줘야 하는 일들이있는데

extension ViewController: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        return false
    }
}

shouldReceive 함수에서 false 를 리턴해주면 view에 넣은 제스쳐가 무시된다.

위의 delegate 함수를 실행시키기 위해서는 superview에 제스쳐를 적용할떄

private func setDismissKeyboardEvent() {
        let gesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        gesture.delegate = self
        self.view.addGestureRecognizer(gesture)
    }
    gesture.delegate = self 를 넣어줘야하 한다.

subview에서의 제스쳐를 인식 시켜줘야할 떄는

shouldReceive 함수에서 false 를 리턴하여

superview의 제스쳐를 무시하면 된다는것이다.

그리고 제스쳐가 필요하지 않은 영역을 터치했을떄는

true를 리턴하여 superview의 제스쳐를 동작시켜야한다.

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        print(touch.view)
        if (touch.view as? UICollectionViewCell) != nil {
            return false
        }
        
        return true
    }

collection view의 셀을 선택하지 않은경우에만 true 를 리턴하였다.

UICollectionViewCell 로 캐스팅이 된경우( cell 선택한 경우) false 를 리턴하여 처리했다.

 

더 쉬운 해결 방법으로는 

상위 뷰에 먹였던 제스쳐에

        tapGestureRecognizer.cancelsTouchesInView = false

설정을 집어 넣어주면 다른 제스쳐를 방해하지 않는다.