평소와 똑같이 UI 만들고 SnapKit 사용해서 레이아웃을 설정하던 도중
딱 코드 한 줄 바꿨는데, 빌드가 안되고 무한루프에 빠져버렸다
(빌드 후 오류가 뜨는 것이 아닌... 무한으로 빌드가 진행됨)
처음에는 컴퓨터 문제인줄 알고 올게왔다 했는데 바꾼 코드 한 줄 주석처리 하니까 정상 빌드가 됐다
여기서 의심된 원인
SnapKit을 사용하여 레이아웃 설정 시 UIScreen.main.bounds와 safeAreaLayoutGuide를 동시에 사용하면 안되는가?
를 토대로 찾아보았다
먼저, UIScreen.main.bounds는 디바이스 화면의 절대적인 크기를 반환한다.
하지만 safeAreaLayoutGuide는 상위뷰와 관련된 상대적인 레이아웃을 기준으로 제공한다
서로 기준이 다르므로 SnapKit이나 Auto Layout 엔진이 이를 동시에 처리하려고 할 때 상호 의존성이 생길 수 있다고 한다
여기서 든 의문은 나는 top의 레이아웃은 safeAreaLayoutGuide를 사용했고 너비는 UIScreen.main.bounds.width로 비율 만큼 너비를 준건데, 다른 위치 속성인데 충돌하는 이유가 뭘까?
오류 발생 원인
1. safeAreaLayoutGuide는 view의 크기에 따라 동적으로 계산된다
2. UIScreen.main.bounds.width는 디바이스 화면 크기를 절대적인 값으로 사용하며, view의 크기와 직접적인 관계가 없을 수 있다
3. 이로인해 Auto Layout 엔진이 동적으로 크기를 조정할 때, view와 UIScreen.main.bounds.width간의 불일치가 생긴다
4. 레이아웃 계산을 계속 반복하다 충돌을 발생시킨다
해결 방법으로는
1. safeAreaLayoutGuide 또는 UIScreen.main.bounds 중 한 가지 기준만 사용한다
searchBarView.snp.makeConstraints {
$0.top.equalTo(view.safeAreaLayoutGuide).offset(20)
$0.leading.trailing.equalToSuperview().inset(20) // Superview를 기준으로 상대적인 너비 설정
$0.height.equalTo(40)
}
2. 부모 뷰 기준을 명시적으로 설정한다 - 일반적으로 안전한 방법
searchBarView.snp.makeConstraints {
$0.top.equalTo(view.safeAreaLayoutGuide).offset(20)
$0.width.equalTo(UIScreen.main.bounds.width * 0.9)
$0.centerX.equalToSuperview() // 뷰를 부모의 중앙에 배치
$0.height.equalTo(40)
}
- top.equalTo(view.safeAreaLayoutGuide):
- searchBarView의 위쪽 위치는 부모 뷰의 safeAreaLayoutGuide를 기준으로 계산합니다.
- width.equalTo(UIScreen.main.bounds.width * 0.9):
- 화면의 절대 크기를 기준으로 너비를 설정합니다.
- centerX.equalToSuperview():
- searchBarView를 부모 뷰의 가로 중앙에 위치시켜 Auto Layout 엔진이 충돌을 방지합니다.
- height.equalTo(40):
- 높이를 고정해 레이아웃을 명확히 정의합니다.
searchBarView의 위치와 크기가 명확히 정의되므로, Auto Layout 엔진이 다시 계산할 필요가 없어지고 무한 루프를 방지할 수 있다
3. 제약조건 간 우선순위를 설정한다(SnapKit의 priority를 사용) - 복잡한 레이아웃에서 특정 제약조건의 충돌을 피하기 위한 대안
searchBarView.snp.makeConstraints {
$0.top.equalTo(view.safeAreaLayoutGuide).offset(20).priority(999)
$0.width.equalTo(UIScreen.main.bounds.width * 0.9).priority(998)
$0.height.equalTo(40)
}
priority(999)는 매우 높은 우선순위로, 일반적으로 중요한 제약 조건에 사용된다
너비를 상대적으로 낮은 우선순위 priority(998)로 설정한다
Auto Layout 엔진이 충돌 상황에서 우선순위가 낮은 제약 조건을 무시하므로, 레이아웃 충돌이나 무한 루프를 방지할 수 있다
'💡 Today I Learned > 오류 잡아라!' 카테고리의 다른 글
[오류] SnapKit 사용 시 No Such file or directory (1) | 2024.12.05 |
---|---|
[오류] UIButton 내부의 image 크기 조절 (2) | 2024.08.30 |
[오류] UITableViewCell에 UICollectionView 추가 오류 (0) | 2024.08.27 |
[오류] 테이블뷰 이벤트 발생 시 UI 작업이 중단되는 현상(스톱워치) (0) | 2024.08.20 |
[오류] TableView 라인이 오른쪽으로 쏠릴 때 (0) | 2024.08.19 |