📱 iOS 플젝 개발일지

[iOS/Swift] UIScrollView 안에 항목별 동적 높이를 가진 투두리스트 구현에 관한 고민 (feat. dynamic contentSize TableView)

dev_zoe 2023. 7. 8. 15:51
반응형

셀프 사이징 셀, dynamic cell height

우선 이렇게 텍스트뷰 길이나 크기에 맞춰서 셀의 크기가 각자 다른 테이블뷰를 구현하려면, 테이블뷰 셀은 다음 속성으로 지정되어야한다.

- rowHeight = UITableView.automaticDimension: 테이블뷰를 load하고 -> 레이아웃을 계산한 다음 -> 셀의 높이값을 알아서 재설정

- estimatedRowHeight = 44.0 : 셀의 높이를 재설정할 때 참고할만한 셀. 즉 재설정 되기 전의 디폴트 셀의 높이를 지정함

 

그리고 그 뒤에 문제가 있었는데, 스크롤뷰 안에 테이블뷰가 여러개 들어가있는 구조라서 API에서 내용을 불러오는 즉시 tableview의 height을 컨텐츠 내용에 맞게 지정해줄 필요가 있어 contentSize.height을 API에서 불러오는 것을 성공할 때마다 각 테이블뷰의 높이로 지정해주었지만, 다음과 같은 이상한 현상이 있었다.

 

🚨 문제 인식

1) 1개라도 1줄 이상으로 넘어가는 셀이 있으면 아래부분이 짤림

 

 

2) 회고 수정화면 초기에 버튼 위치가 이상함

 

3) 작성 / 수정 시 + 버튼을 통해 항목을 추가하면 빈틈이 생김

 

 

세 가지 방식 모두, 테이블뷰의 contentSize가 업데이트되면 해당 사이즈로 높이를 업데이트 시켜주는 방식으로 해서 scrollview가 contentSize에 맞게 스크롤되게 했는데, 이 contentSize가 이슈가 되는 것으로 보였다.

내가 해결해야하는 문제는 내용이 짤려보이지 않게끔, 정상적으로 스크롤되게 수정하는 것 + 하단 버튼이 떠보이지 않게 하는것

 

✅ 문제 해결 과정

* contentSize와 intrinsicContentSize의 차이점

 

- contentSize: UIScrollView, UITableView(UIScrollView 상속함)의 ContentView의 size, 즉 스크롤 가능한 모든 영역

https://developer.apple.com/documentation/uikit/uiscrollview/1619399-contentsize

 

contentSize | Apple Developer Documentation

The size of the content view.

developer.apple.com

- intrinsicContentSize: 고유 컨텐츠 크기 -> 이에 맞게 오토레이아웃이 조건을 자동으로 설정해주므로 개발자가 크기를 지정해주지 않아도 되는 크기

https://velog.io/@eddy_song/intrinsic-content-size

 

오토레이아웃이 자동 설정하는 조건, 고유 콘텐츠 크기(Intrinsic Content Size)

콘텐츠 허깅, 컴프레션 저항... 이 조건들은 다 뭐지?

velog.io

위 글을 보니까 뭔지는 알겠는데 TableView나 ScrollView에는 어떻게 적용되는지 자료를 못찾겠어서 직접 테스트해봤다.

 

차례대로 테이블뷰의 intrinsicContentSie, contentSize를 찍어보았는데 contentSize는 증가하나 intrinsicContentSize는 계속 -1인 것을 확인할 수 있었다.

그래서 스크롤뷰의 contentSize를 명확하게 지정하기 위해서는 UITableView의 contentSize를 활용하여 적절하게 지정할 필요가 있음을 확인할 수 있었다.

 

*dynamic cell과 동적 내용 (API 호출에 따른) 테이블뷰의 동적 높이를 지정하기 위한 과정

 

https://stackoverflow.com/questions/34429534/dynamic-uitableview-height

 

Dynamic UITableView height

I would like to set the UITableView to match the height for all the contents in the table view. This is my storyboard The problem with this is the top and bottom ImageView is always static on the

stackoverflow.com

https://velog.io/@heunb/Dynamic-ContentSize-TableView

 

Dynamic ContentSize TableView

사수가 없으면 알아서 좋은 코드를 많이 찾아보면 된다. 그 소스를 찾는게 좀 일인데 그래도 다를 깔쌈한 프로젝트 코드들을 많이 봐야 한다. 스오풀이나 블로그 글 처럼 자잘한 코드블록도 물

velog.io

이 2가지 글이 많이 참고가 되었다.

 

1️⃣ 동적 높이의 셀과, 동적 테이블뷰의 contentSize를 계산하기 위해서는 다음과 같은 설정을 해야한다.

위에서 설명한 rowHeight, estimatedRowHeight을 설정하기

 

2️⃣ 아래와 같은 Custom TableView 만들기

final class RetrospectTableView: UITableView {

    override func layoutSubviews() {
        super.layoutSubviews()
        
        if bounds.size != self.intrinsicContentSize {
            self.invalidateIntrinsicContentSize()
        }
    }
    
    override var intrinsicContentSize: CGSize {
        return contentSize
    }

}

- layoutSubViews에서 테이블뷰의 cell 위치와 크기를 결정하게 되는데, 이 때 결정된 bounds의 크기와 intrinsicContentSize가 서로 다를 경우 invalidateIntrinsicContentSize를 통해 달라진 내용 갱신

 

3️⃣ 테이블뷰 내용이 변함에 따라 height을 업데이트해야할 경우, 아래와 같이 제약을 잡고 업데이트 진행

이후에 내용의 변화가 발생하면, 아래와 같이 업데이트

 

날 많이 괴롭힌 이친구 드디어,,, 해결 끄읕

반응형