Ios autolayout cover

오토 레이아웃으로 iOS 앱 쉽게 개발하기

소개

iPhone의 다양한 해상도를 지원하기 위해 오토 레이아웃이 필수가 되고 있습니다. 코드 양을 줄일 수 있는 오토 레이아웃으로 쉽게 개발하기라는 주제로 강연하겠습니다.

IntrinsicContentSize

컨텐츠 고유 사이즈는 UILabel, UIButton, UIImageView 등 대부분의 뷰에 있습니다. 레이블을 만들 때 직접 너비와 높이를 지정하지 않아도 되는 이유가 바로 이 컨텐트 고유 사이즈가 있기 때문입니다. 이미지뷰 역시 이미지 크기에 맞게 컨텐트 고유 사이즈가 설정됩니다. 이렇게 대부분의 뷰들은 고유 사이즈, Intrinsic size를 가지며, 표시되는 내용이 변경될 때 이 값도 함께 변경됩니다. 하지만 컨테이너 역할을 하는 일부 뷰들은 고유 사이즈가 없기 때문에 예를 들어 UIView를 넣고 오토 레이아웃을 중앙으로 잡으면 오류가 일어납니다.

Constraint

iOS-AutoLayout-constraint1

오토 레이아웃을 사용하다 보면 빨간색으로 뷰 사이에 생기는 선들을 볼 수 있는데 이것이 제약 조건, Constraint를 지키지 못했을 때 생기는 오류입니다. 이렇게 많은 제약조건 위배 오류가 보이면 도대체 어디서부터 잘못됐는지 알 수 없어 혼란스러울 수 있습니다.

이런 개발 뉴스를 더 만나보세요

iOS-AutoLayout-constraint2

오른쪽 그림의 경우 제약에 대해 부족한 값이 있으므로 이를 넣어주면 해결되는 경우가 많습니다. 만약 왼쪽 그림처럼 다른 제약이 추가된다면 자동으로 계산된 부모의 값과 직접 넣은 부모의 값이 다르므로 또 제약 조건이 맞지 않아 오류가 생깁니다. 이런 경우에는 자식의 너비 중 하나를 없애주면 자동으로 알맞게 계산하므로 다시 해결됩니다.

Priority & isActive

iOS-AutoLayout-priority1

우선순위, Priority는 UILayoutPriority로 설정할 수 있으며 1에서 1000까지의 값을 가집니다. Required는 1000, DefaultHigh는 750, DefaultLow는 250의 기본값이 있습니다. Cut the rope라는 게임을 생각하면 이해가 쉬운데, 세 가지 우선순위로 제약조건이 걸려있는 경우 1000이 가장 높은 영향력을 가지며, 1000이 없어진 경우 750, 750이 없어진 경우 250, 순차적으로 연결된다고 생각하면 됩니다.

iOS-AutoLayout-priority2

먼저 심슨 하단으로부터의 거리를 60, 우선순위를 1000으로 잡고, 다시 하단으로부터의 거리를 200으로 잡고 우선순위를 900으로 잡았습니다. 그러면 처음에는 심슨이 하단에서 60만큼 떨어져서 그려지게 됩니다. 하지만 우선순위 1000을 끊으면 심슨이 우선순위 900의 값을 따라 하단에서 100만큼 올라가게 됩니다.


// Strong으로 연결해야 비활성에서 활성화 가능
IBOutlet var bottomConstraint: NSLayoutConstraint!

// ...

UIView.animate(withDuration: 0.6) {
  self.bottomConstraint.isActive = !self.self.bottomConstraint.isActive
  self.view.layoutIfNeeded()
}

Constraint의 isActive를 true/false로 변경하면 해당 값을 활성화/비활성화할 수 있습니다. 단, 이때 해당 Constraint가 weak으로 연결되면 ARC 문제로 해제될 경우가 있으므로 Strong으로 연결해야 합니다.

LayoutRelation


public enum NSLayoutRelation : Int {
  case lessThanOrEqual
  
  case equal
  
  case greaterThenOrEqual
  
}

제약 조건을 코드로 제어해서 여러 뷰의 위치를 조정할 수도 있습니다. 제약을 추가로 코드로 제한하는 것은 좀 귀찮을 수 있으므로 switch 문으로 만들면 편리합니다.

iOS-AutoLayout-LayoutRelation

스토리보드에서는 도넛의 y축 값을 -100, 우선순위 200으로 설정하고 도넛과 심슨 사이의 간격을 40보다 크거나 같게, 우선순위는 250으로 설정했습니다. 그러면 40보다 크던 간격의 값이 40으로 유지되면서 점차 위로 밀려 올라가게 됩니다.

Content Hugging & Compression Resistance

Content Hugging과 Compression Resistance에 대해서도 살펴보겠습니다. 인터페이스 빌더에서 찾을 수 있는데 고유 사이즈가 가지고 있는 것 중에 방향별로 두 개의 제약 조건을 추가해준다고 이해하면 됩니다.

iOS-AutoLayout-hugging

먼저 Content Hugging은 고유 사이즈의 최대 크기에 제한을 두는 것입니다. 위 그림처럼 너비의 고윳값이 108인 레이블의 Hugging 값을 1000으로 주고 우선순위 900, 제약을 500으로 주면, Hugging의 우선순위 1000이 제약의 우선순위 900보다 크므로 레이블의 크기는 최대 108보다 커지지 않게 됩니다.

iOS-AutoLayout-resistance

반면 Compression Resistance는 최소 크기에 제한을 두는 것입니다. 앞서와 비슷하게 레이블의 Compression Resistance를 1000으로 주면, Resistance의 우선순위 1000이 제약의 우선순위 900보다 크므로 너비의 고유 값인 108보다 작아지지 않게 됩니다.

iOS-AutoLayout-hug-res

따라서 왼쪽 그림처럼 왼쪽 뷰의 Hugging을 251, 오른쪽을 250으로 준다면 글이 길어질수록 아래처럼 파란색 뷰의 영역이 늘어나게 됩니다. 한편 오른쪽 그림처럼 Hugging과 Resistance를 둘 다 큰 값으로 준다면 주황색 뷰의 영역이 커지게 됩니다. Content Hugging과 Compression Resistance는 스토리보드에서 충분히 경험해보는 것을 추천합니다.

ScrollView + Auto Layout

스크롤뷰와 오토 레이아웃을 함께 사용하는 것을 까다로워하는 분이 많은데요. 데모처럼 스크롤뷰 안에 뷰를 넣으면 제약 조건을 위배하게 되는데 물론 세로로 긴 스크롤뷰라면 높이 값이 의미가 없지만, 스토리보드 상의 오류를 해결하려면 일단 뷰의 너비와 높이를 스크롤뷰와 같게 해주고 높이 제약의 우선순위를 1로 주면 됩니다. 또한, Placeholder의 Remove at build time을 체크해서 빌드 시에 제거하도록 해도 좋습니다. 이렇게 하면 평상시와 마찬가지로 오토 레이아웃 작업을 매끄럽게 할 수 있어서 편리합니다. 뷰의 우선순위를 1로 놨기 때문에 다른 뷰가 들어오는 경우 해당 뷰의 고유 사이즈의 우선순위가 높게 작용하게 됩니다.

정리

더 자세한 오토 레이아웃 설정은 동영상의 데모를 확인해 주세요. 코드로 작업하는 것보다 간편하게 스크롤 뷰와 오토 레이아웃을 사용할 수 있습니다.


Let us go는 iOS 개발자로 일하시는 분, 이제 막 시작한 분, 그리고 이제 시작하려 하는 분 모두가 모여 서로 가지고 있는 지식을 공유하며 소통하고 서로 어울려 친해질 수 있는 편한 자리입니다.

본 영상과 글은 Let us go의 비디오 스폰서인 Realm에서 제공합니다. 모바일 개발자가 더 나은 앱을 더 빠르게 만들도록 돕는 Realm 모바일 데이터베이스Realm 모바일 플랫폼을 통해 핵심 로직에 집중하고 개발 효율을 높여 보세요! 공식 문서에서 단 몇 분 만에 시작할 수 있습니다. 또한 Realm 홈페이지에서는 모바일 개발자를 위한 다양한 최신 기술 뉴스와 튜토리얼을 제공하고 있으니 즐겨찾기하고 자주 들러 주세요!

다음: Realm Obj-C와 Realm Swift의 새로운 기능을 소개합니다.

General link arrow white

컨텐츠에 대하여

이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.

김태완

4 design patterns for a RESTless mobile integration »

close