DirTy™의 하루일과/DirTy™의 가당찮은iOS

[IOS] 스토리보드를 이용한 오토레이아웃(Auto Layout)

DirTy™ 2016. 2. 26. 15:16

화면 레이아웃을 변경하거나 해상도에 따라 뭔가를 맞출때 autoresizingmask를 이용한 방법으로도 하고

직접 계산해서 frame, bound를 각각 사이즈별로 변경해도 되고 또 각 해상도 마다 스토리보드를 각각 만들어서

해상도에 맞게끔 보여줘도 되고... 뭐 결과가 중요하니 방법은 가지각색이다.


그래도 요즘에 가장 많이(?) 사용하는 오토레이아웃에 대해 알아보겠다.

목표는 간단히 테스트용으로 아래의 사진과 같은 화면을 만드는 것이다.





오토레이아웃은 말그대로 보면 레이아웃을 자동으로 잡아준다는 말 같지만

사실 뷰의 크기와 위치를 조절하는 주체는 개발자가 아닌 레이아웃 시스템에 따라 결정된다는 뜻이다.

결국 기기의 해상도에 따라서 제약(Constraints)을 개발자가 걸어놓으면 제약사항에 기반한 레이아웃 시스템에 따라

알아서 늘어나고 줄어나고 하는 것이다.


제약(Constraints)을 생각할때는 연습장에 일단 뷰에 대한 그림을 그려놓고 골똘히 생각해보게 된다.

많은 오브젝트들이 한 뷰에 존재할 경우 기준을 잘 잡아야 하는데  그러지 못할경우 수정할시 엄청난 고민을 하게된다. ㅎㅎ


서두가 길었고 일단 스토리 보드를 한번 열어보자. 화살표가 있는곳을 아마도 집중적으로 사용할 것 이다.



위 그림과같이 확대해서 보면 첫번째 그림에 있는건 stack view라고 iOS9부터 지원이 되는 아직까지는 괴랄한 놈이다.

여러 뷰 들을 담을 수 있는 컨테이너라고 생각하면 되고 자동으로 정렬 되는 기능이 있다.

iOS10이 나온다면 아마 자주 쓰게 될 기능인것 같은데 지금은 시기상조인 기능 ㅠㅠ


두번째 네모박스 두개 비스무리한건 Align에 관한 탭이다.

정렬에 관한 탭이다. 센터에 맞출건지 베이스라인으로 삼을건지 등등....





세번째 네모박스 하나를 둘러싸고 있는듯한 그림은 Pin에 관한 탭이다.

슈퍼뷰 혹은 다른 뷰들에 대해 어떻게 반응 할 건지 제약을 걸어주는 탭이다.


마지막4번째 탭은 Resolve Auto Layout Issues라는 탭인데

오토 레이아웃 문제를 해결? 할수 있는 탭이다. 간단한 뷰들의 집합이라면 이기능만으로도 꽤 유용하다.



실전으로 넘어가보자. 아래 그림과같이 이미지뷰를 클릭하고 Align을 눌러서 Horizontally in Container를 체크해보자.


그러면 아래 그림과 같이 빨간 줄이 생기는데 제약사항이 부족하거나 뭔가 안맞으면 빨강 혹은 노랑선이 생기게 된다.

현재 Horizontally in Container에 대한 제약사항만 넣었기 때문에 뭔가 설정이 부족한 것이다.

Pin을 눌러서 그림과 같이 Width, Height 위, 아래 부분을 클릭해서 Add 4 Constraints를 클릭하자.


그러면 빨간줄이 사라지고 이미지 뷰에 대한 제약사항에 대해서는 일단 만족한 결과를 받아내게 된다.

시뮬레이터를 실행하여 실행 결과를 한번 보도록 하자. 아래와 같이 이미지뷰가 중앙위치에 고정이 되었다.



이미지뷰를 필두로 이제 밑의 이름 Label에 제약을 설정해보자.

이름 Label은 이미지뷰를 Center로 잡고 이지뷰와 이름 Label사이를 8정도 띄우고

아래 http://ddirty.tistory.com버튼과도 8정도 거리를 띄우자.



이제 시뮬레이터를 실행하여 보자. 아래와같이 이름 Label도 중앙에 잘 자리잡았다.


다음은 http://ddirty.tistory.com 버튼의 제약사항을 설정해보자.

이름 Label과 같은 방식으로 해보자. 아래 긴글이 들어있는 레이블과의 간격을 8을 주고 이름레이블에 센터를 맞추자.





시뮬레이터를 실행해보자. 아래와같이 버튼도 중앙에 잘 맞춰진것이 확인되었다.


이제 아래 글이 잘리고 있는 Label의 설정을 해보자. 글자수가 많아서 아래와같이 Lines를 5로 설정했다.



아래와 같이 Pin 설정을 해주었다.



시뮬레이터를 실행해보니 Label이 4줄로 디바이스 해상도에 맞게 잘 나오는게 확인된다.



마지막으로 컨테이너뷰에 제약을 설정하자. Pin 설정은 아래와 같이 하였다.



시뮬레이터를 실행해보면 전부다 중앙쪽 정렬에 깔끔하게 정리가 되었다.

가로모드로 실행하여 봐도 설정한데로 아래 사진과 같이 맞게 나온다.



간단하게 Auto Layout에 대해서 알아보았다. 이외에도 Priority Multiplier등도 있는데

이에대해 간단하게 보도록 하겠다.


설정 해놓은 제약 사항에 대해 클릭을 해보면 

First Item Relation SecondItem Constant Priority Multiplier와 같은 옵션들이 존재한다.



보면 짐작가겠지만 FistItem은 자신 즉 이름 Label 이고 Second Item은 이미지뷰가 된다.

제약 설정시 이름 Label을 이미지뷰에 센터로 잡아 놓았기 때문에 그렇다.


Relation은 first Item과 Second Item이 어떤 상황이냐를 판단하는데에 있다. 아래와 같이 세가지 옵션이 준비되어 있다.

Greater Than or Equal, 크거나 같거나

Equal, 같거나

Less Than or Equal 작거나 같거나


프로젝트 진행하면서 복잡한 구조의 뷰를 다뤄본적이 없어서인지 아직 이놈까지는 나도 제대로 건드려 보진 않았다. 

더욱 자세히 알고 싶다면 아래 apple 개발자 사이트에서 정보를 찾아보자.

https://developer.apple.com/library/ios/recipes/xcode_help-IB_auto_layout/chapters/EditingConstraintAttributesintheAttributesInspector.html


Constant는 속성 값이다. 현재 First Item과 Second Item사이에 값은 8로 설정되어있다.

제약 사항이 맞지 않는다면 이값을 수정해보자. 간격이 늘고 줄고가 보일 것이다.


Priority는 제약의 우선순위를 지정하는 속성으로 1~1000 의 값을 할당할 수 있다.

일반적으로 숫자값을 직접 할당하기 보다는 아래와 같이 UILayoutPriority 열거형을 사용한다.

 

enum {

UILayoutPriorityRequired = 1000,

UILayoutPriorityDefaultHigh = 750,

UILayoutPriorityDefaultLow = 250,

UILayoutPriorityFittingSizeLevel = 50,

}; typedef float UILayoutPriority;

 

열거형을 보면 대충 감이 오겠지만 숫자가 높을수록 우선순위가 높고 100보다 작은 UILayoutPriorityFittingSizeLevel을 사용하면 레이아웃 시스템이 임의로

조절 가능하게 된다. 또 레이아웃 시스템에서 발생한 오류를 레이아웃 시스템 스스로 해결하게 됩니다.(모든 오류를 해결 하지는 못함...)


Multiplier는 상대적인 크기의 레이아웃을 배치하는데 사용하면 아주 유용하다.

아래의 그림은 빨간색 버튼1 파란색 버튼2에 대해 위의 레이블과 동등한 width를 갖고

빨간색 버튼은 Label의 width의 40% 파란색 버튼은 60%만큼만 주겠다고 가정하고 만들었다.

옵션은 아래와 같이 주었다. Multiplier도 응용하면 상당히 유용하게 사용 가능하다.



간단하게 알아본다고 했는데 꽤나 길어진 포스팅 이었다.

초보 개발자 분들에게 많은 도움이 되길 바란다.