본문 바로가기

iOS/학습정리

iOS) 오토 레이아웃과 오토 리사이징

Auto Layout

제약조건 속성

제약조건은 다음과 같이 적용된다.

Item1의 항목 = Item2의 항목 * Multiplier + Constant

제약조건의 속성으로는 다음의 세 가지가 있다.

  • Relation: 동일, 이상, 이하
  • Multiplier, Constant: 제약조건의 값
  • Priority: 우선순위

제약조건 경쟁

  • Relation
    • 제약조건 간 경쟁에 영향을 미치는 요소로 관계(relation)가 있다. 예를 들어 레이블 A에 대해 중앙에 위치해야 하고, 왼쪽으로 100 포인트 이상 떨어져야한다는 제약조건이 있다고 가정해보자. 레이블 A는 크기 유지라는 제약조건이 있을 때 경쟁이 발생할 수 있다.
  • Priority
    • 우선순위가 높은 것이 먼저 적용된다. 우선순위는 최대 1000까지의 자연수로 표시되며 수가 클 수록 높은 우선순위를 가진다.
  • 에러
    • 동시에 만족할 수 없는 제약조건의 경우 에러를 발생시킨다. 예를 들어 오른쪽으로 80만큼 떨어지는 제약조건과 40만큼 떨어지는 제약조건이 동시에 존재하면 충돌로 인한 에러가 발생한다.

뷰의 컨텐츠 크기

오토레이아웃 우선순위 중 Content Hugging PriorityContent Compression Resistance Priority이 있다.

Content Hugging Priority은 고유 크기보다 늘어나지 않으려는 성질로 기본값은 251이다.
Content Compression Resistance Priority는 고유 크기보다 작아지지 않으려는 성질로 기본값은 750이다.

Autoresizing Mask

An integer bit mask that determines how the receiver resizes itself when its superview’s bounds change.

Auto Layout과의 차이점

오토레이아웃과의 차이점은 오토레이아웃은 부모뷰 뿐만 아니라 형제뷰끼리의 관계도 설정할 수 있지만 오토리사이징은 부모뷰에 대해서만 관계를 설정할 수 있다는 것이다.

헷갈리기 쉬운 특징

translatesAutoresizingMaskIntoConstraints

A Boolean value that determines whether the view’s autoresizing mask is translated into Auto Layout constraints.

인터페이스 빌더에서 뷰를 작성하면 디폴트로 false 이지만 코드로 작성할 경우 디폴트 값이 true이다. 코드로 작성하면서 Auto Layout을 동적으로 변환할 경우 반드시 false로 지정해줘야한다.

만일 이 값이 true이면, 해당 뷰의 오토리사이징 마스크에 의해 지정된 constraints를 자동으로 만든다. 뷰의 크기나 위치를 수정하고 싶으면 뷰의 frame, bounds, center properties를 변경하여햐 한다.

오토리사이징 마스크는 constraints 완전하게 만드므로 추가적인 constraints를 줄 수 없다. 자체적으로 오토레이아웃을 사용하기 위해서는 이 값이 false여야 한다.

뷰에 constraints를 추가했는데 이유없이 에러가 왕창 뜨면 일단 translatesAutoresizingMaskIntoConstraints 값이 false로 지정되었는지 확인해보자!

leadingAnchor vs leftAnchor

leadingAnchor은 상대적인 위치를 나타내고leftAnchor는 절대적인 위치를 의미한다.

locale과 관련된 것인데, left -> right가 일반적인 진행 방향인 지역이 있고, 반대로 right -> left가 일반적인 진행 방향인 지역이 있다. 이 때 앱에서 leftAnchor를 사용하여 뷰의 위치를 지정하면 일부 지역에서는 반대로 보일 수 있다.

따라서 절대적으로 왼쪽을 표시하고 싶을 때가 아니면 leadingAnchor를 사용하는게 좋다. 마찬가지로 rightAnchor 대신 trailingAnchor를 가용하는 것이 좋다.

Order of Constraints

Constraints를 사용할 때 순서에 주의해야한다.

만일 자식뷰의 끝이 부모뷰 끝에서 40만큼 떨어져있기를 원한다면 어떻게 해야할까?

childView.bottomAnchor.constraints(
    equalTo: parentView.safeAreaLayoutGuide.bottomAnchor,
    constant: 40
)

이렇게 쓰기 쉬운데 제약조건은 childeView.bottomAnchor = parentView.bottomAnchor + 40이 되므로 화면을 벗어나게 된다. 40 대신 -40을 사용하든지 childViewparentView의 순서를 바꿔야한다.

childView.bottomAnchor.constraints(
    equalTo: parentView.safeAreaLayoutGuide.bottomAnchor,
    constant: -40
)
parentView.bottomAnchor.constraints(
    equalTo: childView.safeAreaLayoutGuide.bottomAnchor,
    constant: 40
)