📱 iOS 플젝 개발일지

[iOS/Swift] 테이블뷰 셀을 꾹 눌러야만 동작하는 이슈(Conflict UITapGestureRecognizer, didSelectRowat)

dev_zoe 2023. 6. 14. 16:35
반응형

🚨 문제 인식

하단 테이블뷰 셀이 한번에 클릭이 안되고, 꾹 눌러야만 인식이 되어 tableView.rx.itemSelected (=didSelectRowAt)이

잘 동작이 되지 않는 현상이 있었다.

 

❗️ 문제 원인

여러 사이트를 통해 원인을 찾아보니 해당 VIewController가 상속하고 있는 BaseViewController에서 화면을 탭했을 때 키보드가 사라지게 하는 액션을 취하기 위해 추가한 UITapGestureRecognizer가 cell의 클릭을 방해하고 있었던 것으로 짐작되었는데

 

https://stackoverflow.com/questions/8904368/conflicting-uitapgesturerecognizer-in-uiview-and-for-uitableview

 

Conflicting UITapGestureRecognizer in UIView and for UITableView

I have a UIView in which I added a UITapGestureRecognizer. Inside that view I also have a subview in which is basically some kind of a UITableView. The question is that why doesn't the UITableView

stackoverflow.com

cancelsTouchesInview를 false로 주면 문제가 해결된다고 해서 적용해보니 해결은 되었다.

그러나 구체적으로 저게 왜 문제였는지가 궁금해서 더 찾아봤다.

 

✅ 문제 해결 과정

 

1) 뷰의 UITapGestureRecognizer란 무엇인가

 

*UITapGestureRecognizer를 정확히 알고 썼던게 아니라서 더 뜯어보기로 했다.

    func dismissKeyboardWhenTappedAround() {
        let tap =
            UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
        tap.cancelsTouchesInView = false //같은 뷰에 여러 tap gesture가 있을 때, 해당 tap이 다른 tap을 방해하지 않기 위한 설정
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard() {
        view.endEditing(false)
    }

- UITapGestureRecognizer: target에 탭 제스처가 발생했을 때 action 파라미터를 실행하는 제스처 인식기

- #selector키워드와 @objc를 붙이는 이유

https://developer.apple.com/documentation/swift/using-objective-c-runtime-features-in-swift

 

Using Objective-C Runtime Features in Swift | Apple Developer Documentation

Use selectors and key paths to interact with dynamic Objective-C APIs.

developer.apple.com

#selector: Objective-C의 코드를 가져온 것으로, 특정 메소드를 가리키기 위한 문법

@objc: Objective-C에서 사용하는 코드라는 의미로 키워드를 붙이는 것이고 위에서 설명한 것처럼 Objective-C 코드를 가져온 것이므로 앞에 해당 키워드를 붙여야만 동작한다.

- view.endEditing(false)의 의미: 

https://developer.apple.com/documentation/uikit/uiview/1619630-endediting

 

endEditing(_:) | Apple Developer Documentation

Causes the view (or one of its embedded text fields) to resign the first responder status.

developer.apple.com

이해가 조금 안되서 블로그를 살펴보니 다음과 같은 글이 있었다.

 

https://jeong9216.tistory.com/158

 

[iOS/Swift] 화면 터치 시 키보드 내리는 방법 / touchesBegan() / endEditing() / first responder

[iOS/Swift] 화면 터치 시 키보드 내리는 방법 / touchesBegan() / endEditing() / first responder 안녕하세요. 개발하는 정주입니다. 오늘은 화면 터치 시 키보드를 내리는 방법에 대해 포스팅하려고 합니다. 해

jeong9216.tistory.com

즉 endEditing을 true로 하게되면 텍스트필드에게 물어보지 않고 강제로 respond에 관한 액션(키보 드 등장)을 종료시킨다는 의미라고 하는것 같다.

 

2) TapGestureRecognizer와 UITableView의 didSelectRowAt의 충돌이 일어나는 이유

- 나는 분명 테이블뷰 셀을 클릭했는데 자꾸 tapGestureRecognizer가 발동이 됐다.

여기서 위에 해결한 방법대로 tap.cancelsTouchesInview를 false로 주면?

 

이 속성은 tapGestureRecognizer가 자기 자신의 역할을 마치고 다른 gesture를 인식할 것인가?

즉 "뷰의 터치를 이후에 취소할 것인가"를 정하는 속성이었다.

그래서 이를 false로 주면 나는 셀을 터치했을 때 VC에 걸린 제스처 인식기에 대한 액션을 먼저 처리하고 그 다음 테이블뷰로 넘어가서 테이블뷰가 자신의 일을 처리한 것이다.

 

 

 

 

반응형