본문 바로가기
IOS App Programming/트러블 슈팅

CollectionView Cell 클릭이 안될때 대체 방법

by B_Tori 2024. 2. 2.

프로젝트 도중 collectionview의 didselectItemAt 함수가 호출되지 않는 문제가 발생하였다.

그래서 여러 가지 시도를 해봤는데 계속해서 되지 않아

didselectItemAt 함수 대신 해 사용할 수 있는 방법을 찾아 정리해볼까 한다.

시도해 봤던 방법

이미지 뷰가 셀 전체를 차지하고 있어 계층 구조 시 셀이 이미지 뷰에 덮어지면서 무언가 꼬여 해당 함수가 호출이 되지 않는 건 아닐까 의심되었다.

isUserInteractionEnabled 속성을 줘봄 ⇒ 실패

isUserInteractionEnabled
뷰에 대한 터치, 누르기, 키보드 및 포커스 이벤트가 무시되고 이벤트 큐에서 제거됨. 기본값은 true

 

그렇다면 나의 가정이 잘못된 것인지 확인해보기 위해

이미지에 여백을 줘 해당 여백을 클릭했을 때 함수가 호출되는지 확인해 보았다.

하지만 함수는 그래도 호출되지 않았다.

이미지 때문에 꼬였을 거 같다는 내 예상은 틀렸었다.

UITapGestureRecognizer로 didselectItemAt 대신하기

UITapGestureRecognizer
단일 또는 다중 탭을 해석하는 개별 제스처 인식기

 

셀을 생성할 때 셀에 addGestureRecognizer를 해준 뒤 탭 했을 때의 동작을 selector로 전달해 준다.

선택한 셀마다 각각의 데이터를 넘겨주기 위해서는 인덱스패치 계산이 필요하다.

didSelectedItemAt은 자동으로 계산해 주지만 UITapGestureRecognizer는 직접 알려줘야 한다.

@objc func tappedCell(_ sender: UITapGestureRecognizer) {
    let point = sender.location(in: collectionView)
    if let indexPath = collectionView.indexPathForItem(at: point) {
        print(indexPath.row)
        let viewController = UserDetailViewController()
        navigationController?.pushViewController(viewController, animated: true)
    }
}

UITapGestureRecognizer의 location함수로 제스처의 위치값을 저장한다.

collectionView.indexPathForItem(at: ) 함수를 통해 해당 좌표의 인덱스패치 값을 구할 수 있다.

func indexPathForItem(at point: CGPoint) -> IndexPath?
컬렉션 뷰의 지정된 지점에 있는 항목의 인덱스 경로를 가져옴.

 

결론

나중에 확인해 보니 베이스뷰컨트롤러와의 충돌로 didselectItemAt 함수가 호출하지 않는 것이었다.

충돌 해결 후 다시 함수를 작성해 보니 잘 호출되었다.

당연히 충돌되는 부분을 찾아 수정 후 함수를 작성하는 것이 좋겠지만

임시적인 방편으로 didselectItemAt 대신에 UITapGestureRecognizer를 사용해서 didselectItemAt처럼 사용할 수 있다는 것을 알았다.

댓글