expandable + dynamic height tableview cell 구현하기
데이터 값에 따라 유동적인 높이를 가진 Tableview를 구현 해야하고
그리고 해당 Tableview는 접기/펼치기 기능이 들어 있어야 할경우의 예시입니다.
우선 Tableview의 기본적인 구현 이 되어있다는 가정하에 진행합니다.
접기 펼치기 기능은 단순히 Row의(cell) 높이를 바꿔 주면 됩니다.
heightForRowAt 함수를 통해 유동적으로 cell의 높이를 지정 해주면 됩니다.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
print("heightForRowAt \(indexPath)")
if helpViewModel.isSelectedCell(indexPath: indexPath) {
return UITableView.automaticDimension
}else {
return 64
}
}
여기서 안펼친경우 64의 고정값을 줬으며
펼친경우 UITableView.automaticDimension 값을 주었습니다.
이렇게되면 isSelectedCell 값에 따라 유동적 으로 필요한 크기 만큼만 차지하게 됩니다.
다만 여기서 automaticDimension 을 사용하기 위해 중요한 부분은 cell의 제약조건이 명확히 주어져야 한다는것입니다. 그렇지 않은경우 올바른 높이 값이 나오지않아 저도 애를 먹었습니다.
automaticDimension 을 사용하여 만약 선택 되었다면 필요한 가장 큰 높이값을 가질것입니다.
선택되지 않았다면 64 값을 가지구요
이제 selectedCell 을 내부 값으로 저장해 사용하면 됩니다.
저장 값으로 indexPath를 사용했습니다. section 이 나뉘어져 있는경우 단순히 index로 구별이 힘들기 때문입니다.
var selectedCellIndex : [IndexPath] = []
func addToSelectedCellIndex(indexPath:IndexPath) {
if isSelectedCell(indexPath: indexPath){
if let index = selectedCellIndex.firstIndex(of: indexPath){
selectedCellIndex.remove(at: index)
}
}else{
selectedCellIndex.append(indexPath)
}
print(selectedCellIndex)
}
func isSelectedCell(indexPath:IndexPath) -> Bool{
return selectedCellIndex.contains(indexPath)
}
선택한 경우 selectedCellIndex 배열에 들어갑니다. 만약 이미 들어있다면 remove를 통해 제거합니다.
즉 toggle 이 더 맞는 표현입니다.
이제 마지막으로 viewController에서 didSelectRowAt 함수만 정의해 주면 됩니다.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
helpViewModel.addToSelectedCellIndex(indexPath: indexPath)
faqTableView.reloadRows(at: [indexPath], with: .automatic)
}
위에서 구현한 addToSelectedCellIndex 함수를 사용하면 됩니다.
그리고 tableView를 reload 하여 테이블의 값을 갱신하면됩니다.
그러면 heightForRowAt 함수가 다시불려 높이값이 변경될 것입니다.