let detailHeaderViewConstraints = [
detailHeaderView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
detailHeaderView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
detailHeaderView.topAnchor.constraint(equalTo: contentView.topAnchor),
detailHeaderView.heightAnchor.constraint(equalToConstant: 360),
// 아래 코드를 넣어야 스크롤이 됨
detailHeaderView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
]
🔥 detailHeaderView를 좌, 우, 상 그리고 높이를 지정했습니다. 하지만 무슨 이유인지 몰라 detailHeaderView 안에 있는 collectionView가 가로 방향으로 스크롤되지 않았습니다.
detailHeaderView.bottomAnchor를 contentView.bottomAnchor에 연결함으로써 스크롤뷰의 내용 크기가 제대로 계산되어 문제를 해결한 것 같습니다.
이로 인해 스크롤뷰가 수직 방향으로 스크롤할 수 있는 충분한 컨텐츠 크기를 인식하게 되어, 스크롤이 제대로 작동하게 된 것입니다. 또한, 이 방식으로 하면 UIScrollView 내의 모든 콘텐츠가 자연스럽게 표시되고, 컬렉션 뷰의 가로 스크롤도 정상적으로 작동할 것입니다.
간단한 원리 설명
- UIScrollView는 자식 뷰들의 크기와 제약 조건에 따라 **컨텐츠 크기(contentSize)**를 계산합니다. 이때, contentView의 하단 제약 조건이 설정되지 않으면, 스크롤뷰가 전체 컨텐츠의 높이를 제대로 계산하지 못해 스크롤이 되지 않는 경우가 발생합니다.
- detailHeaderView.bottomAnchor를 contentView.bottomAnchor에 연결하면서 스크롤뷰는 이제 컨텐츠의 크기를 정확히 인식하게 되어, 스크롤 기능이 제대로 작동하게 된 것입니다.
요약
- detailHeaderView의 하단 제약 조건을 설정해 줌으로써, 스크롤뷰의 컨텐츠 크기 계산 문제를 해결하셨습니다.
- 이제 스크롤이 제대로 동작할 것이며, 컬렉션 뷰의 가로 스크롤도 함께 정상적으로 작동할 것입니다.
🔥 heightAnchor로는 높이 계산이 안되나?
⭐️ heightAnchor를 설정해도 스크롤이 안 되는 이유 ⭐️
heightAnchor를 설정했음에도 스크롤이 되지 않은 이유는 UIScrollView가 컨텐츠의 전체 크기를 계산하는 방식과 관련이 있습니다. 스크롤뷰는 자식 뷰들의 제약 조건을 통해 **컨텐츠 크기(contentSize)**를 자동으로 결정합니다. 그러나 이 과정에서 스크롤뷰는 뷰의 높이와 더불어 자식 뷰의 모든 제약 조건을 고려해야 합니다.
즉, 높이만 설정하는 것으로는 충분하지 않으며, 자식 뷰의 상하 제약 관계가 명확히 설정되어야 합니다.
핵심 원리: 스크롤뷰 내에서의 제약 조건 설정
- 스크롤뷰의 컨텐츠 크기 계산:
UIScrollView는 내부에 추가된 모든 자식 뷰의 제약 조건을 종합해서 **컨텐츠 크기(contentSize)**를 자동으로 계산합니다.- 상단 앵커 (topAnchor)와 하단 앵커 (bottomAnchor)가 모두 설정되어야 스크롤뷰는 자식 뷰가 차지하는 전체 높이를 인식할 수 있습니다.
- 만약 상단, 하단 제약 조건이 모두 설정되지 않으면 스크롤뷰는 자식 뷰가 얼마만큼의 높이를 차지해야 하는지 제대로 인식하지 못합니다.
- heightAnchor와 bottomAnchor의 차이:
- heightAnchor는 자식 뷰의 고정된 높이를 설정하지만, 스크롤뷰는 그 높이가 화면 밖으로 벗어나도 자동으로 인식하지 않습니다. 이 때문에 **하단 제약 조건(bottomAnchor)**이 필요합니다.
- bottomAnchor는 자식 뷰가 스크롤뷰의 하단까지 얼마큼 이어지는지 알려줍니다. 이 제약이 없으면, 스크롤뷰는 자식 뷰의 하단을 정확히 알지 못해 컨텐츠의 끝을 제대로 계산하지 못하고 스크롤이 되지 않게 됩니다.
예시 상황
let detailHeaderViewConstraints = [
detailHeaderView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
detailHeaderView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
detailHeaderView.topAnchor.constraint(equalTo: contentView.topAnchor),
detailHeaderView.heightAnchor.constraint(equalToConstant: 360)
]
이 코드에서 heightAnchor로 360의 높이를 설정했지만, 스크롤뷰는 자식 뷰의 끝을 알지 못하기 때문에 제대로 스크롤되지 않습니다. 상단 앵커(topAnchor)와 하단 앵커(bottomAnchor)가 둘 다 설정되어야, 스크롤뷰는 자식 뷰의 전체 크기를 알 수 있습니다.
이를 보완한 코드가 다음과 같습니다:
let detailHeaderViewConstraints = [
detailHeaderView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
detailHeaderView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
detailHeaderView.topAnchor.constraint(equalTo: contentView.topAnchor),
detailHeaderView.heightAnchor.constraint(equalToConstant: 360),
detailHeaderView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) // 추가한 하단 제약 조건
]
이제 스크롤뷰는 detailHeaderView가 상단부터 하단까지 얼마만큼의 영역을 차지하는지 정확히 계산할 수 있게 되어 스크롤이 제대로 작동합니다.
요약
- heightAnchor는 자식 뷰의 고정된 높이만 설정해 주지만, 스크롤뷰는 자식 뷰의 전체 범위를 알기 위해 상단과 하단 제약 조건이 모두 필요합니다.
- 상하 제약 조건이 모두 설정되지 않으면, 스크롤뷰는 자식 뷰가 어디까지 있는지 알지 못해 스크롤이 되지 않습니다.
- bottomAnchor를 추가함으로써 스크롤뷰는 자식 뷰의 전체 높이를 계산할 수 있게 되어 스크롤이 정상적으로 작동하게 됩니다.
'iOS > Swift' 카테고리의 다른 글
공공 API를 통해 데이터를 가져오는 중에 발생한 오류 해결 (1) | 2024.09.21 |
---|---|
위치정보를 받아오는 방법 (0) | 2024.09.18 |
외부 API를 받는 데이터 함수의 데이터 타입 관리 (0) | 2024.09.06 |
데이터 모델 이름을 바꿔야 한다면? (0) | 2024.09.06 |
enum을 통해 api 함수 관리해보기 (0) | 2024.08.31 |