본문 바로가기
프로그래밍 놀이터/iOS

[iOS Study] 오토 레이아웃 소개

by 돼지왕 왕돼지 2016. 3. 3.
반응형


 [iOS Study] 오토 레이아웃 소개


출처 : 아론 힐리가스의 iOS 프로그래밍


(lldb), 1000, Add Missing Constraints, align, alignment rectangle, ambiguous layout, Auto Layout, Baseline, Bottom, centerx, centery, Clear Constraints, constraint, Container, control drag, Delete, deployment info, descenders, Devices, exerciseAmbiguityInLayout, Frames, G, hasAmbiguousLayout, height, Interface builder, IOS, ios study, ios tutorial, iPhone, layout attributes, Leading, Left, margin, nearest neighbor, P, PIN, PO, po [[UIWindow keyWindow] _autolayoutTrace], priority, Reset to Suggested Constraints, Resolve Auto Layout Issues, Right, shift, shift selection, Top, trailing, UILabel, UITextField, UIWindow, unable to simultaneously satisfy constraints, Universal, universal application, Update Constraints, Updates Frames, viewDidLayoutSubviews, width, [iOS Study] 오토 레이아웃 소개, _autolayoutTrace, ~ipad, ~iphone, 가장 가까운 이웃, 경고, 계산, 기준선 아래, 네이밍, 독, 드래그, 디버거, 디버그용, 디센더, 레이아웃, 레이아웃 속성, 레티나, 로드, 모호, 모호한 레이아웃, 배포, 불총족한 제약조건, 브레이크 포인트, 비공개 인스턴스 메소드, 비레티나, 사각형, 상위 뷰, 아랍어, 아론 힐리가스, 아이패드, 아이폰, 애플, 여백, 오류, 오토 레이아웃, 우선 순위, 우선순위, 유니버설 앱, 유니버셜 앱, 유용, 인터페이스 빌더, 장치에 따른 xib, 장치의 방향, 절대 좌표, 점선, 접미사, 정렬 사각형, 정사각형, 제약 조건, 제약 조건 무시, 제약조건 목록, 제약조건 삭제, 제약조건 충돌, 주황색, 주황색 지지대, 추천, 컨테이너, 컨트롤, 코드, 콘솔, 크기, 파란 선, 포인트, 폰트, 픽셀, 필수 제약 조건, 힌트


-

아이패드와 아이폰 모두에서 실행 가능한 단일 앱을 유니버설 앱(Universal application) 이라 한다.



-

Deployment info 섹션으로 이동하여 Devices 팝업에서 iPhone 을 Universal 로 변경하면 된다.



-

절대 좌표 체계는 레이아웃이 깨지기 쉽다.

미리 화면 크기를 알고 있다고 가정하기 때문이다.


오토 레이아웃을 사용하여 상대적인 방식으로 뷰들의 레이아웃을 기술할 수 있다.

이것은 실행 시에 frames 를 결정하도록 해준다.

따라서 frames 의 정의가 프로그램이 실행 중인 장비의 화면 크기를 고려할 수 있도록 한다.



-

레티나 장비는 비레티나 장비보다 두 배 많은 픽셀을 가지고 있지만 포인트로는 같은 크기의 화면을 가진다.


아이폰/아이팟 ( 4S 와 그 이전 모델 ) : 320 x 480

아이폰/아이팟 ( 5와 그 이후 모델 ) : 320 x 568

아이패드 : 768 x 1024



-

오토 레이아웃 시스템은 뷰를 위해 정렬 사각형(alignment rectangle) 이라는 사각형을 하나 더 가지고 작동한다.

이 사각형은 여러 레이아웃 속성(layout attributes)으로 정의된다.


Width / Height


Top / Bottom / Left / Right


CenterX / CenterY


Baseline     보통 bottom 속성과 동일. 그러나 UITextField 는 정렬 사각형의 bottom 대신에 baseline 을 표시할 텍스트의 밑부분이 되도록 정의한다.

     이것은 텍스트 필드 바로 아래의 뷰로 인해 “디센더"(descenders, ‘g’, ‘p’ 와 같이 기준선 아래로 내려가는 글자들 ) 가 모호해지는 것을 막기 위해서이다.


Leading / Trailing     이 값은 UITextField 와 UILabel 과 같은 텍스트 기반 뷰에 사용한다.

     장치의 언어가 왼쪽에서 오른쪽으로 읽는 언어라면 leading 속성은 left 속성과 같고, trailing 속성은 right 속성과 같다.

     오른쪽에서 왼쪽으로 읽는 아랍어와 같은 언어라면, leading 속성은 right 값이고 trailing 속성은 left 값이다.



-

XIB 파일에서 기본적으로 모든 뷰는 정렬 사각형을 가지고 모든 뷰 계층은 오토 레이아웃을 사용한다.

하지만 기본 설정은 원하는 대로 동작하지 않아 작업이 필요하다.


제약조건(constraint) 집합을 제공한다.

이 제약조건들은 오토 레이아웃 시스템이 뷰 계층의 각 뷰를 위한 레이아웃 속성을 결정하고 그것으로 정렬 사각형을 결정하도록 해준다.



-

제약 조건(constraint)은 뷰 계층구조에서 하나 이상의 뷰를 위한 레이아웃 속성을 결정하는데 사용되는 특정 관계를 정의한다.


모든 레이아웃 속성에 대한 제약조건을 가져야 하는 것은 아니다.

어떤 값은 제약조건에서 직접 가져올 수 있고, 또 어떤 것은 관련 레이아웃 속성값으로부터 계산해낼 수 있다.



-

만약 모든 제약조건을 고려한 뒤에도 레이아웃 속성에 여전히 모호하거나 빠진 값이 있다면

오토 레이아웃 시스템에서 오류와 경고를 내보낼 것이다.



-

인터페이스 빌더에서 제약조건으로 사용하려면, 뷰의 가장 가까운 이웃(nearest neighbor)을 찾는 법을 이해해야 한다.

가장 가까운 이웃은 일정 방향에서 가장 가까운 형제 뷰를 의미한다.


만약 뷰가 특정 방향에서 형제가 아무도 없다면 가장 가까운 이웃은 컨테이너(container)로도 불리는 자신의 상위 뷰이다.







-

제약조건은 인터페이스 빌더를 사용하거나 코드로 추가할 수 있다.

애플은 가능한 한 인터페이스 빌더를 사용해 제약조건을 추가하는 것을 추천한다.



-

우하단 왼쪽에서 두 번째 아이콘을 클릭하여 Pin 메뉴를 나타낼 수 있다.

Pin 메뉴 맨 위의 값 네 개는 캔버스에서 툴바와 가장 가까운 이웃 사이의 여백을 나타낸다.


제약조건으로 변경하려면 중앙 정사각형으로부터 값들을 분리하는 주황색 지지대를 클릭한다.

지지대가 직선으로 변할 것이다.


툴바의 높이를 제한하려면 Height 옆의 박스를 체크한다.



-

캔버스 왼쪽의 독에서 방금 추가한 제약 조건을 볼 수 있다.



-

XIB 파일에서는 제약조건이 자동으로 적절한 뷰에 추가된다.

제약조건을 프로그래밍으로 만들기 위해서는 생성과 추가 과정이 구분된다.

어느 뷰가 제약조건을 갖는지는 어떤 뷰들이 제약조건에 영향을 받는지에 달려있다.



-

독에서 제약조건들 중 어느 하나를 선택하면 캔버스에 해당 제약조건을 표시하는 파란 선이 나타날 것이다.

(일부 제약조건들은 다른 것들보다 보기 힘들 수도 있다.)

뷰를 선택하면 그 뷰에 영향을 주는 모든 제약조건을 보여줄 것이다.


독에서 제약조건을 선택하거나 캔버스에서 제약조건이 표시된 선을 선택한 후 Delete 키를 눌러 제약조건을 삭제할 수 있다.



-

제약조건을 나타내는 선들이 주황색일 때가 있는데,

색이 다른 것은 텍스트 필드가 오토 레이아웃에서 정렬 사각형을 명확히 지정하기에 제약조건이 충분하지 않다는 것을 뜻한다.



-

Shift 키를 누른 채로 여러 개의 View 를 선택 한 후,

우하단 가장 왼쪽 아이콘을 누르면 Align 메뉴가 나온다.



-

캔버스에서 컨트롤 드래그하여 제약조건을 추가하는 방법도 있다.

한 뷰에서 다른 뷰로 드래그한다.

마우스 버튼을 놓으면 추가할 수 있는 제약조건 목록이 나타난다.

이 목록은 드래그 방향과 드래그를 시작한 뷰와 끝난 뷰를 기반으로 나타난다.


시프트 키를 누른 채로 선택하면 여러 제약 조건을 한번에 선택할 수 있다.



-

각 제약조건은 여러 제약조건이 충돌했을 때 어떤 제약이 이기는지를 결정짓는 우선 순위 등급을 가진다.

우선순위는 1부터 1000 사이의 값이다.

1000 은 필수 제약조건이다.

기본적으로 제약조건은 필수이다.

따라서 우리가 추가한 모든 제약조건은 필수적이다.

이것은 제약조건 충돌시 우선순위 등급이 아무런 도움이 되지 못함을 의미한다.

대신에 오토 레이아웃은 불충족한 제약조건에 관한 문제를 보고한다.


충돌을 해결하려면 하나를 지우거나(때때로 원인은 명백한 우연이다.) 또는 모든 제약조건을 유지하려면 우순선위 등급을 줄여야 한다.



-

계층구조상의 모든 뷰의 정렬 사각형을 결정하고 아이폰과 아이패드에 원하는 레이아웃을 적용하기 위해서

xib 에 오토 레이아웃을 허용하고 제약조건들을 추가한다.

순전히 주어진 제약조건의 수만으로도 문제가 발생하기 쉽다.

또한 제약조건을 빠뜨릴 수 있고, 제약조건들이 서로 충돌하거나 캔버스에서 뷰를 표시하는 법과 충돌한 제약조건이 있을 수 있다.



-

모호한 레이아웃은 제약조건 집합을 충족할 방법이 여러 가지 있을 때 발생한다.

이는 일반적으로 적어도 하나의 제약조건이 빠져 있음을 뜻한다.



-

인터페이스 빌더는 두 속성을 만족하는 제약조건은 하나의 제약조건으로 인식한다.



-

아래 코드는 모호한 레이아웃이 있을 때, 판단조건을 바꾸는 코드이다.


if ([subview hasAmbiguousLayout]){

     [subview exerciseAmbiguityInLayout];

}


exerciseAmbiguityInLayout 메소드는 오토 레이아웃을 허용하여 결국 레이아웃이 어떻게 될지를 보여주는 순전히 디버그용 도구이다.

따라서 배포될 프로그램에는 이 코드를 남겨두면 안 된다.



-

불충족한 제약조건 문제는 둘 이상의 제약조건이 충돌할 때 발생한다.

이는 종종 뷰가 너무 많은 제약조건을 가지고 있음을 뜻한다.


이 때 Xcode 의 디버깅 창으로부터 unable to simultaneously satisfy constraints 라고 알려주고 힌트도 준다.

콘솔에 이 문제와 관련된 모든 제약조건이 나열된다.

마지막으로 유효한 프레임을 가질 수 있도록 제약 조건 중 하나가 무시될 것이라고 알려준다.







-

XIB에서 뷰의 프레임이 제약조건과 일치하지 않으면 잘못 배치된 뷰 문제가 발생한다.

이는 실행 중에 그 뷰의 프레임이 현재 캔버스에 나타난 것과 일치하지 않는다는 것을 뜻한다.


주황색의 사각형 점선이 나타날 것이다. 이는 실행 중에 나타날 프레임이다.

기존 제약조건들은 우리가 드래그한 곳이 아닌 이 사각형이 위치한 그 라벨에 존재할 것이다.


우하단의 세번째 아이콘을 선택하면 Resolve Auto Layout Issues 메뉴가 나온다.



-

Resolve Auto Layout Issues 는 다음과 같은 옵션이 있다.


Updates Frames     뷰의 프레임을 제약조건과 일치하도록 조절한다.


Update Constraints     뷰의 제약조건을 프레임과 일치하도록 조절한다.


Add Missing Constraints     모호한 레이아웃을 가진 뷰에 필수 제약조건을 추가하여 모호함을 없앤다.

     하지만 새 제약조건은 원하던 것이 아닐 수 있기에, 다시 한번 점검해야 한다.


Reset to Suggested Constraints     뷰에서 기존 제약조건을 제거하고 새 제약조건을 뷰에 추가한다.

     이 추천 제약조건은 뷰의 상황에 의존적이다.

     뷰가 상위뷰의 상단 부근에 있다면 추천 제약조건은 아마 상단에 뷰를 고정시킬 것이다.


Clear Constraints     모든 제약조건을 없앤다.

     뷰에 명시적으로 추가된 제약조건이 없다면 기본 고정 위치와 크기 제약조건을 뷰에 추가할 것이다.



-

UIWindow 는 비공개 인스턴스 메소드 _autolayoutTrace 를 가지고 있다.

이 메소드는 윈도우의 뷰 계층 전부를 그린 문자열을 반환한다.

그리고 모호한 레이아웃을 가진 뷰에 AMBIGUOUS LAYOUT 이라는 이름을 붙인다.


이를 사용하는 최선의 방법은 해당 뷰가 화면에 나타난 이후에 호출될 코드에 브레이크 포인트를 지정하는 것이다.

브레이크포인트에 도달하면 디버거에서 다음을 입력하고 엔터를 누른다.


(lldb) po [[UIWindow keyWindow] _autolayoutTrace]


이는 예상대로 UI 가 보이지 않을 때 매우 유용한다.

하지만 어디서 문제가 발생했는지는 확인할 수 없다.



-

앱을 실행할 장치의 종류에 따라 완전히 다른 뷰들이 필요한 뷰 컨트롤러를 가질 수도 있다.

이러한 경우에 각 장치 종류에 맞게 두 개의 XIB 파일을 만들 수 있다.


각 장치에 따라 적당한 XIB 파일을 로드하는 뷰 컨트롤러를 얻으려면 간단히 파일명에 접미사를 추가하면 된다.


ViewController~iphone.xib

ViewController~ipad.xib


이러한 방식의 XIB 파일 네이밍은 실행 시에 뷰 컨트롤러가 자동으로 올바른 파일을 찾아 로드하도록 한다.


XIB 파일을 분리한다고 해서 오토 레이아웃을 대체할 수 있는 것이 아님을 기억하자.

여전히 두 파일에 제약조건을 추가해야 한다.

또한 오토 레이아웃은 사용자 언어나 선호하는 폰트 크기, 장치의 방향 등에 따라 인터페이스가 적절하게 대응하도록 한다.



cf) viewDidLayoutSubviews  는 화면에 처음 뷰가 나타날 때나 뷰의 크기가 바뀔 때마다 호출된다.









반응형

댓글