프로그래밍/iOS

[iOS] tableView.indexPath(for: UITableViewCell)이 nil이 반환될 때

turu 2021. 3. 9. 01:05

 

indexPath(for:)

 

Declaration

func indexPath(for cell: UITableViewCell) -> IndexPath?

 

우선 셀은 지속적으로 재사용되고 테이블뷰에 의해 관리되고 있으므로 외부에서 cell을 직접참조를 해서 어떤 작업을 하는 것은  피해야한다.

 

원인:

nil이 발생하는 원인은 아직 추가되지 않은 셀, 셀이 표시가 되지 않고 있음, indexPath가 범위를 벗어남 이 있다고 한다.

그러나 내 경우는 화면상에 셀이 보이고 있는 상태인데 계속 nil이 반환되었다.

정확히는 모르지만 셀 내부 컨텐츠뷰들을 수정하고나면 어떠한 이유로 인해서 nil이 반환하는 일이 생기는 것 같다.

 

조건:

textView의 텍스트를 수정하지 않으면 nil이 발생하는 일이 없었다.

 

전후 상황:

1. textView delegate가 구현되어있음

2. 해당 셀의 contentView에 있는 textView가 focus를 받고 수정된 상태에서, reloadSection을 호출하게 되면,

순차적으로 resignFisrtResponder -> notifyDidEndEditing -> ... -> textView의 textViewDidEndEditing

와 같은 메서드들이 순차적으로 호출된다.

3. textViewDidEndEditing에서 cell의 indexPath를 가져오기위해서  indexPath(for:)를 사용하면 nil이 반환된다.

 

reloadSection/reloadRows와 같은 정해진 방법이 있는 메서드는 내부에서 resignFirstResponder를 호출하기 때문에 delegate 메서드들 안에서 section/row를 지우고나서 직접reload하면, indexPath가 안맞아떨어지게 호출되었다.

 

해결방법:

reloadSection/Row과정에 delegate메서드들이 호출되는 구조라면, reloadSection/Row 전에 미리 데이터소스 수정삭제/리로드와 관련된 메서드를 호출한다.

 

나는 2번에서 reloadSection와 같이 resignFirstResponder->delegate 메서드 호출 이런 식으로 되는 메서드를 호출하기 전에,

해당 textView객체에게 textView.resignFirstResponder를 호출하게 했다.

반응형