[번역] Unsatisfiable Layouts - Debugging Auto Layout

작성일 :

Unsatisfiable Layouts


Unsatisfiable Layouts은 시스템이 현재 제약 조건 세트에 대한 유효한 솔루션을 찾을 수 없을 때 발생합니다. 두 개 이상의 필수 제약 조건이 모두 동시에 참일 수 없기 때문에 충돌합니다.

Identifying Unsatisfiable Constraints


종종 Interface Builder는 디자인 타임에 충돌을 감지할 수 있습니다. 이러한 경우 Interface Builder는 여러 가지 방법으로 오류를 표시합니다.

  • 충돌하는 모든 제약 조건은 캔버스에 빨간색으로 그려집니다.
  • Xcode는 충돌하는 제약 조건을 이슈 탐색기에 경고로 나열합니다.
  • Interface Builder는 문서 개요의 오른쪽 상단 모서리에 빨간색 공개 화살표를 표시합니다.
image01

화살표를 클릭하여 현재 레이아웃의 모든 오토 레이아웃 이슈 목록을 표시합니다.

Interface Builder는 종종 이러한 문제에 대한 수정을 권장할 수 있습니다. 자세한 내용은 자동 레이아웃 도움말의 뷰 컨트롤러, 창 또는 루트 뷰에 대한 레이아웃 이슈 해결을 참조하십시오.

NOTE

Interface Builder에서 제공하는 즉각적인 피드백을 통해 유효한 레이아웃을 훨씬 쉽게 만들 수 있지만 가능한 모든 레이아웃 오류를 찾을 수는 없습니다.

예를 들어 Interface Builder는 캔버스의 현재 크기에서만 충돌을 감지합니다. 그러나 일부 충돌은 루트 보기가 특정 지점 이상으로 확장되거나 축소될 때(또는 콘텐츠가 특정 지점 이상으로 확장되거나 축소될 때)에만 발생합니다. Interface Builder는 이러한 오류를 감지할 수 없습니다.

따라서 Interface Builder가 식별하는 모든 문제를 항상 수정해야 하지만 명백한 오류를 수정하는 것만으로는 충분하지 않습니다. 지원하려는 전체 화면 크기, 방향, 동적 유형 크기 및 언어에 대해 런타임 테스트를 계속 수행해야 합니다.

시스템이 런타임에 만족할 수 없는 레이아웃을 감지하면 다음 단계를 수행합니다.

  • 오토 레이아웃은 충돌하는 제약 조건 집합을 식별합니다.
  • 충돌하는 제약 조건 중 하나를 깨고 레이아웃을 확인합니다. 시스템은 유효한 레이아웃을 찾을 때까지 계속해서 제약 조건을 해제합니다.
  • 오토 레이아웃은 콘솔에 대한 충돌 및 깨진 제약 조건에 대한 정보를 기록합니다.

이 폴백(fallback) 시스템을 사용하면 앱이 계속 진행되면서도 사용자에게 의미 있는 것을 제시하려고 시도할 수 있습니다. 그러나 제약 조건을 깨는 효과는 레이아웃마다, 심지어는 빌드마다 크게 다를 수 있습니다.

대부분의 경우 누락된 제약조건은 눈에 보이는 효과가 없을 수 있습니다. 뷰 계층 구조는 예상한 대로 정확하게 나타납니다. 다른 경우에는 누락된 제약 조건으로 인해 뷰 계층 구조의 전체 섹션이 잘못 배치되거나 크기가 잘못 조정되거나 완전히 사라질 수 있습니다.

명백한 효과가 없을 때 오류를 무시하고 싶은 유혹이 종종 있습니다. 결국 오류는 앱의 동작을 변경하지 않습니다. 그러나 뷰 계층 구조 또는 SDK를 변경하면 깨진 제약 조건 집합이 변경되어 갑자기 분명히 깨진 레이아웃이 생성될 수 있습니다.

따라서 만족할 수 없는 제약조건 오류를 발견하면 항상 수정하십시오. 테스트 중에 명백하지 않은 오류를 포착할 수 있도록 UIViewAlertForUnsatisfiableConstraints에 대한 기호 중단점을 설정합니다.

Preventing Unsatisfiable Constraints


Unsatisfiable constraints은 상대적으로 수정하기 쉽습니다. Unsatisfiable constraints이 발생하면 시스템에서 이를 알려주고 충돌하는 제약 조건 목록을 제공합니다.

오류에 대해 알게 되는 즉시 솔루션은 일반적으로 매우 간단합니다. 제약 조건 중 하나를 제거하거나 선택적 제약 조건으로 변경하십시오.

그러나 더 자세히 검토할 가치가 있는 몇 가지 일반적인 문제가 있습니다.

  • 프로그래밍 방식으로 뷰 계층 구조에 뷰를 추가할 때 만족할 수 없는 제약 조건이 종종 발생합니다. 기본적으로 새 뷰에는 translatesAutoresizingMaskIntoConstraints 속성이 YES로 설정되어 있습니다. Interface Builder는 캔버스에서 뷰에 제약 조건을 그리기 시작할 때 자동으로 이 속성을 NO로 설정합니다. 그러나 프로그래밍 방식으로 뷰를 생성하고 배치할 때 고유한 사용자 지정 제약 조건을 추가하기 전에 속성을 NO로 설정해야 합니다.
  • Unsatisfiable constraints은 뷰 계층 구조가 너무 작은 공간에 표시될 때 종종 발생합니다. 일반적으로 뷰가 액세스할 수 있는 최소 공간을 예측하고 레이아웃을 적절하게 디자인할 수 있습니다. 그러나 국제화(internationalization)와 dynamic type으로 인해 뷰의 콘텐츠가 예상보다 훨씬 커질 수 있습니다. 가능한 순열의 수가 증가함에 따라 레이아웃이 모든 상황에서 작동한다는 것을 보장하기가 점점 더 어려워집니다. 대신, 예측 가능하고 제어된 방식으로 레이아웃이 실패하도록 실패 지점을 구축할 수 있습니다. 일부 필수 제약 조건을 우선 순위가 높은 선택적 제약 조건으로 변환하는 것을 고려하십시오. 이러한 제약 조건을 사용하면 충돌이 발생할 때 레이아웃이 중단되는 위치를 제어할 수 있습니다. 예를 들어 실패 지점에 999의 우선 순위를 지정합니다. 대부분의 상황에서 이 높은 우선 순위 제약 조건은 필요한 것처럼 작동합니다. 그러나 충돌이 발생하면 우선 순위가 높은 제약 조건이 해제되어 레이아웃의 나머지 부분이 보호됩니다. 마찬가지로, 본질적인 콘텐츠 크기가 있는 뷰에 필수 콘텐츠 허깅 또는 컴프레셔 레지스턴스 우선 순위를 부여하지 마십시오. 일반적으로 컨트롤의 크기는 이상적인 실패 지점 역할을 합니다. 컨트롤은 레이아웃에 의미 있는 영향을 주지 않고 조금 더 크거나 작을 수 있습니다. 예, 고유 콘텐츠 크기로만 표시되어야 하는 컨트롤이 있습니다. 그러나 이러한 경우에도 일반적으로 레이아웃이 예측할 수 없는 방식으로 중단되도록 하는 것보다 약간 떨어진 컨트롤을 사용하는 것이 좋습니다.