🚨 문제 인식
하단 테이블뷰 셀이 한번에 클릭이 안되고, 꾹 눌러야만 인식이 되어 tableView.rx.itemSelected (=didSelectRowAt)이
잘 동작이 되지 않는 현상이 있었다.
❗️ 문제 원인
여러 사이트를 통해 원인을 찾아보니 해당 VIewController가 상속하고 있는 BaseViewController에서 화면을 탭했을 때 키보드가 사라지게 하는 액션을 취하기 위해 추가한 UITapGestureRecognizer가 cell의 클릭을 방해하고 있었던 것으로 짐작되었는데
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
#selector: Objective-C의 코드를 가져온 것으로, 특정 메소드를 가리키기 위한 문법
@objc: Objective-C에서 사용하는 코드라는 의미로 키워드를 붙이는 것이고 위에서 설명한 것처럼 Objective-C 코드를 가져온 것이므로 앞에 해당 키워드를 붙여야만 동작한다.
- view.endEditing(false)의 의미:
https://developer.apple.com/documentation/uikit/uiview/1619630-endediting
이해가 조금 안되서 블로그를 살펴보니 다음과 같은 글이 있었다.
https://jeong9216.tistory.com/158
즉 endEditing을 true로 하게되면 텍스트필드에게 물어보지 않고 강제로 respond에 관한 액션(키보 드 등장)을 종료시킨다는 의미라고 하는것 같다.
2) TapGestureRecognizer와 UITableView의 didSelectRowAt의 충돌이 일어나는 이유
- 나는 분명 테이블뷰 셀을 클릭했는데 자꾸 tapGestureRecognizer가 발동이 됐다.
여기서 위에 해결한 방법대로 tap.cancelsTouchesInview를 false로 주면?
이 속성은 tapGestureRecognizer가 자기 자신의 역할을 마치고 다른 gesture를 인식할 것인가?
즉 "뷰의 터치를 이후에 취소할 것인가"를 정하는 속성이었다.
그래서 이를 false로 주면 나는 셀을 터치했을 때 VC에 걸린 제스처 인식기에 대한 액션을 먼저 처리하고 그 다음 테이블뷰로 넘어가서 테이블뷰가 자신의 일을 처리한 것이다.