반응형

Ray로 부터 알림: 축하한다. 여러분들이 이루어냈다. iOS 6 Feast 단어를 널리 알리는 것을 도와줘서, 첫번째 iOS 6 튜토리얼을 미리 공개하게 되었다!

이 튜토리얼은 새로운 책인 iOS 6 튜토리얼의 하나의 챕터의 축약된 버젼이다. Matthijs Hollemans가 작성하였다. 그는 iOS Apprentice Series를 작성한 사람이다. 재미있게 즐겨라!

이 포스트는 iOS 튜토리얼 팀 맴버이면서 iOS 개발자와 디자이너의 경험이 있는 Matthijs Hollemans가 작성하였다.

가로/새로 방향 모두에서 보기좋게 앱을 만들려고 하다가 좌절한 적이 있는가? iPhone과 iPad 둘 다 지원하는 화면 레이아웃을 만드는 것은 미치기 직전으로 만든다. 절망은 더 이상 없다. 여러분에게 좋은 소식을 가져왔다.

항상 같은 크기를 보증하는 화면을 위한 유저 인터페이스를 디자인 하는 것은 어렵지 않지만, 화면 프레임이 바뀌면 UI 구성요소의 위치, 크기 또한 이러한 새로운 장비의 크기에 맞게 변경되어야 한다.

지금까지 화면 디자인이 합리적으로 복잡했다면, 레이아웃 적용을 지원하기 위해 많은 코드를 작성해야 만 했다. 더 이상 이런 경우가 없다는 것이 다행 일 것이다. iOS 6는 iPhone과 iPad에 오토 레이아웃이라는 놀라운 새로운 기능을 제공한다.

오토 레이아웃은 앱에서 다른 화면 크기를 쉽게 지원하는 것을 만들어 줄 뿐만 아니라, 보너스로 간단하게 지역화를 만들게 지원한다. 지원하고 싶어하는 모든 언어를 위해서 새로운 nib이나 스토리보드를 만들지 않아도 된다. 그리고 히브리어와 아랍어와 같은 오른쪽에서 왼쪽으로 쓰는 언어도 포함해서 지원한다.

이 튜토리얼은 인터페이스 빌더를 사용하여 오토 레이아웃을 시작하는 방법을 보여준다. iOS 6 튜토리얼에서는 이 튜토리얼 보다 더욱더 추가되었고 지식으로 만드는 방법과 코드를 통해서 오토 레이아웃의 전체 능력을 발휘하는 방법을 보여주는 완전히 새로운 장을 갖추고 있다.

간식과 좋아하는 카페인 음료를 들고 오토 레이아웃 마스터가 될 준비를 해라!

스프링과 스트러츠의 문제점

“스프링과 스트러츠” 모델로 알려진 오토싸이즈 마스크를 잘 알고 있을 것이다. 오토싸이즈 마스크는 슈퍼뷰의 크기가 변경될 때 뷰에 어떤 일을 결정한다. 유연한 또는 고정 여백(스트러츠)를 가지고 있는가? 그리고 너비와 높이(스프링)에 어떤 일이 있는가?

예를들어 슈퍼뷰가 넓어지면, 유연한 너비를 가진 뷰는 비례적으로 넓어질 것이다. 그리고 고정된 오른쪽 여백을 가진 뷰의 오른쪽 가장자리는 항상 슈퍼뷰의 오른쪽 가장자리에 고정될 것이다.

오토싸이즈 시스템은 간단한 경우에 잘 동작 된다. 그러나 레아아웃이 더 복잡해질 때 제대로 동작하지 않는다. 스프링과 스트러츠가 단순하게 자르지 않는 예를 살펴보자.

Xcode를 실행하고 Single View Application 템플릿을 기반으로 새로운 프로젝트를 생성한다. 앱 이름을 “StrutsProblem” 으로 작성한다. iPhone을 선택하고 스프링보드를 비활성화 한다.

프로젝트 옵션

인터페이스 빌더에서 ViewController.xib를 클릭하여 연다. 어떤 작업을 하기 전에, 우선적으로 nib의 Auto Layout을 비활성화 한다. 이 작업은 File 인스펙터에서 한다.

오토레이아웃 비활성화

“Use Autolayout” 체크박스에 체크를 해제한다. 지금 nib은 예전 스트러츠-스프링 모델을 사용한다.

메모:Xcode 4.5 이상에서 생성된 nib이나 스토리보드 파일에서는 오토 레이아웃이 기본적으로 활성화 된다. 오토 레이아웃은 iOS 6 기능이기 때문이다. 만약 Xcode 4.5를 사용해서 iOS 5 앱을 만들기를 원한다면, nib이나 스토리보드 파일을 “Use Autolayout” 체크박스에 체크를 해제해서 비활성화 해야 한다.

3개의 뷰를 메인 뷰에 끌어다 놓고 다음과 같이 정렬하라.

세로 디자인

구별하기 위해서 각각의 뷰에 색상을 부여하여 어떤 뷰가 어떤 뷰인지 확인 할 수 있다.

각 뷰는 윈도우의 경계에 20 포인트를 준다. 뷰 사이의 패딩에도 20포인트를 준다. 아래의 뷰는 280 포인트 넓이를 주고, 위의 2개의 뷰는 각각 130 포인트 넓이를 준다. 모든 뷰는 200 포인트 높이를 준다.

앱을 실행하고 시뮬레이터를 회전 시킨다. 또는 디바이스를 가로로 회전 시킨다. 앱의 화면이 다음과 같이 나타날 것이다. 생각과는 많이 다르다.

잘못된 가로화면

메모: HardwareRotate Left 그리고 Rotate Right 메뉴 옵션을 사용하여 시뮬레이터를 회전 시킬 수 있다. 또는 Cmd 키를 누른상태에서 좌 또는 우 화살표 키를 누르면 된다.

대신에 가로화면은 다음과 같이 보이길 원했다.

올바른 가로화면

3개의 뷰의 오토싸이징 마스크에 명백하게 원하는 무언가를 조금 남겨야 한다. 왼쪽-위 뷰의 오토싸이징 설정을 다음과 같이 변경한다.

왼쪽-위 뷰의 오토싸이징

이것은 위와 왼쪽의 가장자리를 고정시킨다. 그러나 아래와 오른쪽 가장자리는 고정시키지 않는다. 그리고 슈퍼뷰의 크기가 변경이 될 때 가로/세로 크기 모두를 변경한다.

비슷하게 오른쪽-위 뷰의 오토싸이징 설정을 변경한다.

오른쪽-위 뷰의 오토싸이징

그리고 아래 뷰는 다음과 같이 변경한다.

아래 뷰의 오토싸이징

앱을 다시 실행하고 가로로 화면을 회전한다. 이제는 다음과 같이 보일 것이다.

잘못된 가로화면 (2)

뷰 사이의 패딩이 잘못되었다. 다른 방법으로 봐도 뷰의 크기가 100% 옳지 않다. 문제는 오토싸이징 마스크가 슈퍼뷰 크기가 변경이 되었을때 뷰에게 변경된 크기를 알려준다는 것이다. 그러나 뷰에게 얼만큼 뷰의 크기가 변경되어야 하는지 알려줄 방법이 없다.

오토싸이즈 마스크로 해결 할 수 있다. 예를 들면 유연하게 넓이와 높이 설정(스프링)을 변경한다. 그러나 3개의 뷰 사이에 20 포인트를 가지도록 완벽하도록 정확하게 보이게 할 수 없다.

 왜?!?!?

스프링과 스트러츠 방법으로 레이아웃 문제를 해결하기 위해서는 불행하게도 몇 줄의 코드를 작성해야 한다.

UIKit가 뷰 콘트롤러에게 유저 인터페이스가 회전하기 전, 회전하는 동안, 회전한 후에 몇 가지 메세지를 보낸다. 이런 메세지를 가로채서 UI 레이아웃을 변경 할 수 있다. 일반적으로 재배치를 원하는 뷰의 프레임을 변경을 하기 위해서는 willAnimateRotationToInterfaceOrientation:duration:을 오버라이드 한다.

그러나 이 작업을 하기 전에 먼저 배치하기 위한 뷰에게 전달할 아웃렛 프로퍼티를 만들어야 한다.

(Xcode 툴바의 Editor 툴셋의 가운데 버튼) Assistant Editor 모드로 전환한다. 3개의 뷰를 각각 ViewController.h:로 콘크롤-드래그 한다.

콘트롤-드래그 아웃렛 프로퍼티

각각 뷰와 3개의 프로퍼티를 연결한다.

@property (weak, nonatomic) IBOutlet UIView *topLeftView;
@property (weak, nonatomic) IBOutlet UIView *topRightView;
@property (weak, nonatomic) IBOutlet UIView *bottomView;

다음 코드를 ViewController.m에 추가한다.

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                        duration:(NSTimeInterval)duration
{
   [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
 
   if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
   ||  toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
   {
       CGRect rect = self.topLeftView.frame;
       rect.size.width = 210;
       rect.size.height = 120;
       self.topLeftView.frame = rect;
 
       rect = self.topRightView.frame;
       rect.origin.x = 250;
       rect.size.width = 210;
       rect.size.height = 120;
       self.topRightView.frame = rect;
 
       rect = self.bottomView.frame;
       rect.origin.y = 160;
       rect.size.width = 440;
       rect.size.height = 120;
       self.bottomView.frame = rect;
   }
   else
   {
       CGRect rect = self.topLeftView.frame;
       rect.size.width = 130;
       rect.size.height = 200;
       self.topLeftView.frame = rect;
 
       rect = self.topRightView.frame;
       rect.origin.x = 170;
       rect.size.width = 130;
       rect.size.height = 200;
       self.topRightView.frame = rect;
 
       rect = self.bottomView.frame;
       rect.origin.y = 240;
       rect.size.width = 280;
       rect.size.height = 200;
       self.bottomView.frame = rect;
   }
}

뷰 콘트롤러가 새로운 방향으로 회전하고 있을 때 이 콜백이 발생한다. 뷰 컨트롤러 방향이 회전할 때 뷰의 크기를 적절하게 변경한다. 이 상황에서는 아이폰의 알려진 화면 크기에 기초로 제공된 하드코딩으로 변경한다. 에니메이션 블록에서 이 콜백이 발생한다. 그래서 크기 변경 에니메이션이 실행된다.

앱을 아직 실행하지 마라. 먼저 다음과 같이 3개 뷰의 오토리싸이징 마스크를 복원해야 한다. 아니면 오토리싸이징 메카니즘은 뷰의 willAnimateRotation에 설정해 놓은 위치와 크기 때문에 크래쉬된다.

오토싸이징 끄기

그것을 해야한다. 앱을 실행하고 가로 방향으로 회전한다. 이제는 뷰가 올바르게 정렬 될 것이다. 다시 세로 방향으로 회전 시키고 모든 것이 잘 어울리는지 확인한다.

잘 동작한다. 그러나 사실 꽤나 간단한 레이아웃을 위해서 많은 양의 코드를 작성했다. 각각의 뷰가 크기 변경을 동적으로 하거나 서브뷰의 갯수가 정해지지 않는 것과 같은 정말 복잡한 레이아웃을 위해 걸리는 노력을 상상해 보아라.

분명히 다른 방법이 있을꺼야

메모: 다른 방법으로 접근하는 방법은 가로와 세로 방향의 nib을 구분해서 만드는 것이다. 디바이스가 회전 될 때 다른 nib의 뷰를 로드하고 기존 것과 교체한다. 그러나 이 방법도 여전히 많은 노력을 필요로 한다. 그리고 1개 대신에 2개의 nib을 관리하므로써 더 많은 문제점을 발생 시킬 수 있다.

오토 레이아웃을 구조하라!

이제 오토 레이아웃과 동일한 효과를 달성하는 방법을 볼 수 있다. 먼저 ViewController.m에서 willAnimateRotationToInterfaceOrientation:duration:을 지운다. 왜냐하면 코드를 작성하지 않고 이러한 작업을 할 것이다.

ViewController.xib을 선택하고 nib 파일의 오토 레이아웃을 활성화 하기 위해 File 인스펙터 패널에서 “Use Autolayout”의 체크박스를 체크한다.

오토 레이아웃 활성화

메모: 오토 레이아웃은 전체 nib 또는 스토리보드 파일을 위해서 항상 활성화 되어 있다. 체크박스가 체크되어 있으면 nib 또는 스토리보드안의 모든 뷰는 오토 레이아웃을 사용한다.

앱을 실행하고 가로 방향으로 회전 시켜라. 이전에 했던 작업과 같이 엉망으로 된 레이아웃이 보여진다.

잘못된 가로화면

오토 레이아웃을 시작하자. Cmd키를 누르고 위의 2개의 뷰(녹색과 노란색)를 클릭한다. 그러면 두 개는 선택된다. Xcode의 Editor 메뉴에서 PinWidths Equally를 선택한다.

Pin widths equally

똑같이 두 개의 뷰를 다시 선택하고 EditorPinHorizontal Spacing을 선택한다. (첫번째 Pin 작업을 수행한 후에 두 개의 뷰가 선택된 상태로 표시됨에도 불구하고, 특별한 레이아웃 관계 디스플레이 모드에 있는 것을 주의해라. 그래서 두 개의 뷰를 다시 선택 해야만 한다.)

왼쪽의Document Outline에서 “Constraints” 이름의 새로운 섹션을 발견했을 것이다. 이 섹션은 nib에 오토 레이아웃이 활성화되면 추가된다. 이 제약조건과 다음 섹션에서 그것들이 어떻게 동작하는지 배울 것이다.

지금은 “Horizontal Space (170)” 위치로 이동하고 리스트로부터 그것을 삭제 한다.

Horizontal Space Constraint

앱을 실행하고 가로 방향으로 회전 시킨다. 이전보다 보기 좋아 보인다. 위쪽 뷰는 적절한 너비와 패딩을 가진다. 그러나 아직 꽤 부족하다.

가로 방향은 거의 마쳤다

Cmd 키를 누르고 3개의 뷰 모두를 선택한다. Editor 메뉴에서 PinHeights Equally를 선택한다.

이제 왼쪽-위 코너의 뷰를 선택하고 아래쪽 뷰를 선택(방금 전처럼 Cmd를 사용하여)하고 EditorPinVertical Spacing를 선택한다.

마지막으로 “Vertical Space (240)” 제약조건을 리스트로부터 삭제한다.

동시에 3개의 뷰를 선택하면 인터페이스 빌더는 다음과 같이 무언가를 보여 줄 것이다.

제약조건

파란색 “T-bar” 모양은 뷰 사이의 제약조건을 나타낸다. 약간 무섭게 보일 수도 있으나 모든 의미를 터득하면 실제로는 매우 간단하다.

앱을 실행하고.. 짜잔~! 한 줄의 코드를 작성하지 않고도 모든 것이 제대로 보인다.

올바른 가로방향

정확하게 무슨 짓을 한 것일까? 얼마나 큰 뷰인지, 그것들이 어디에 위치해 있는지를 하드코딩을 요구하기 보다, 오토 레이아웃은 레이아웃의 뷰가 각각 어떻게 관련되어 있는지 표현 할 수 있다.

제약조건으로 알려진 다음 관계를 레이아웃에 삽입한다.

  • 왼쪽-위과 오른쪽-위 뷰는 항상 같은 넓이(Pin의 “Widths Equally” 명령어)를 가진다. .
  • 왼쪽-위과 오른쪽-위 뷰의 사이에 수평(Pin의 “Horizontal Spacing” 명령어)으로 20 포인트 패딩이 있다.
  • 모든 뷰는 항상 같은 높이(Pin의 “Heights Equally” 명령어)를 가진다.
  • 위쪽 뷰와 아래쪽 하나의 뷰 사이에는 수직(Pin의 “Vertical Spacing” 명령어)으로 20 포인트 패딩이 있다.

그리고 화면 크기가 변경되었을 때 그 방법은 뷰를 배치 해야하는 곳과 행동하는 방법인 오토 레이아웃으로 표현하기에 충분하다.

잘했어요

메모: 또한 “Use Autolayout” 체크박스를 토글 할 때 스프링-스트러츠 레이아웃으로부터 가져온 몇 가지 제약조건이 있다. 뷰와 화면의 가장자리 사이의 각각의 여백에 대해 “이 뷰는 항상 위/아래/왼쪽/오른쪽 가장자리로 부터 20포인트 거리에 위치한다.”와 같은 기본적으로 말하는 제약조건이 있다.

Document Outline에서 모든 제약조건을 볼 수 있다. Document Outline에 제약조건을 클릭을 하면, 인터페이스 빌더는 제약조건 주변에 흰색 아웃라인을 그리고 눈에 뛰기 위해 그것에 그림자를 추가해서 뷰를 강조 한다.

선택된 제약조건

제약조건은 실제 객체(NSLayoutConstraint 클래스)이다. 그리고 또한 속성을 가진다. 예를들면 위쪽 두개의 뷰 사이의 패딩을 추가하는 제약조건(“Horizontal Space (20)”라고 이름을 가진)을 선택하고 Attributes 인스팩터로 전환한다. Constant 필드를 편집하여 여백의 크기를 변경 할 수 있다.

Constraint 속성

100으로 설정하고 앱을 다시 실행한다. 이제 여백이 더 넓어졌다.

”가로화면에서

앱의 뷰를 설명 할 때 오토 레이아웃은 스프링과 스트러츠 보다 더 많은 표현이다. 이 튜토리얼의 끝에서 제약조건과 인터페이스 빌더에서 다른 종류의 레이아웃을 만들기 위해 그것들을 적용하는 방법에 대해 배울 것이다.

오토 레이아웃의 작동 방법

위의 테스트 드라이브에서 본 바와 같이, 오토 레이아웃의 기본 도구는 제약조건이다. 제약조건은 두개의 뷰 사이의 기하학적 관계를 설명한다. 예를 들어 다음과 같은 제약조건이 있을 수 있다.

”레이블의 오른쪽 가장자리는 버튼 B의 왼쪽 가장자리와 둘 사이의 빈 공간 20포인트로 연결되어 있다. ”

오토 레이아웃은 모든 제약조건을 가지고 모든 뷰의 이상적인 위치와 크기를 계산하기 위해 몇 가지 수학적 계산한다. 더 이상 뷰의 프레임을 설정 할 필요가 없다. 뷰에 설정한 제약조건을 전부 기초로 하여 오토 레이아웃은 그것을 대신 수행한다.

오토 레이아웃 이전에는 인터페이스 빌더로 특정 좌표에 배치를 하거나, 사각형을 initWithFrame:에 전달하거나, 뷰의 프레임, 범위(bound) 또는 중앙 속성을 설정하여 뷰의 프레임을 하드코딩 했었다.

간단하게 만들 앱을 위해서 구체적으로 다음 그림과 같이 프레임을 설정 한다.

Struts 좌표

각각의 뷰에 오토싸이징 마스크를 설정한다

Struts 오토싸이징 마스크

저 방법으로는 더 이상 화면 디자인을 생각하는 방법을 사용 할 수 없다. 오토 레이아웃으로 해야 할 모든 것은 다음과 같다.

스트러츠 대신에 오토 레이아웃

뷰의 크기와 위치는 더 이상 중요하지 않다. 오직 제약조건의 문제이다. 물론 새로운 버튼 또는 레이블을 캔버스에 드래그 할 때 특정 크기를 가진다. 그리고 특정 위치에 드롭을 할 것이다. 그러나 그것은 오직 제약조건을 넣기위해 인터페이스 빌더에 사용을 전달하는 디자인 도구이다.

의미하는 것 처럼 디자인 하기

제약조건을 사용하는 가장 큰 이점은 더 이상 적절한 위치에 뷰를 나타나게 하기 위해 좌표를 설정하지 않아도 된다. 대신에 오토 레이아웃에 어떻게 뷰가 다른 뷰와 연관되는지를 설명하면 된다. 그리고 오토 레이아웃은 모든 어려운 일을 대신 해 줄 것이다. 의도에 의한 디자인이라고 불린다.

의도에 의한 디자인을 할 때, 수행하고 싶은 것이 무엇인지 그러나 필요하지는 않지만 그것을 수행하는 방법을 표현한다. “버튼의 왼쪽-위 코너의 좌표는 (20, 230)” 이라고 하는 대신에, 이제는 다음과 같이 할 수 있다.

“버튼은 그것의 슈퍼뷰에 수직의 가운데에 있다. 그리고 그것은 슈퍼뷰의 왼쪽 가장자리로부터 고정된 거리에 위치한다.”

이 설명을 사용하여 오토 레이아웃은 자동적으로 버튼이 나타나는 위치를 계산한다. 슈퍼뷰가 크거나 작은 것은 문제가 아니다.

의도된 디자인 다른 예와 오토 레이아웃은 다음 지침을 모두 처리 할 수 있다.

“이 두 개의 텍스트 필드는 항상 같이 크기여야 한다.”
“이 두 개의 버튼은 항상 같이 움직여야 한다.”
“이 네 개의 레이블은 항상 오른쪽 정렬이여야 한다.”

이것은 유저 인터페이스 디자인을 더 설명적으로 만든다. 제약조건과 시스템이 자동적으로 프레임 계산하는 것을 단순하게 정의한다.

첫 번째 셋션에서 단지 몇 개의 뷰를 가지는 레이아웃이 가로/세로 두 방향을 제대로 레이아웃을 보여주기 위해서 꽤 많은 작업이 필요하다는 것을 보았다. 오토 레이아웃을 사용하면 저러한 모든 노력을 건너 뛸 수 있다. 제약조건을 제대로 설정한다면 레이아웃은 가로/세로 두 방향에서 어떠한 변경 없이 작동해야 한다.

오토 레이아웃을 사용하는 다른 중요한 이점은 지역화이다. 예를 들면 독일어로 된 텍스트는 매우 길기로 악명 높다. 레이블에 딱 맞게 하려면 머리가 아프다. 화면에 나타나는 것을 필요로 하는 콘텐츠를 기초로 해서 레이블의 크기를 자동으로 조절 가능하기 때문에 오토 레이아웃은 모든 이러한 작업을 대신한다. 그리고 나머지는 제약조건과 관련된다.

독일어, 프랑스어, 또는 다른 언어 지원을 추가하는 것은 제약조건, 텍스트 번역의 설정의 문제이다. 그게 전부이다.

프랑스어

오토 레이아웃의 익히는 가장 좋은 방법은 그것을 다루는 것이다. 그래서 이 튜토리얼의 남은 부분에서 할 일이다.

메모: 오토 레이아웃은 화면회전을 위해서만 유용한게 아니다. 이것은 크기가 다른 화면을 적용하기 위해서 확대 및 축소를 쉽게 할 수 있다. 큰 화면의 아이폰과 작아진 아이패드의 계속되는 루머가 사실로 되었을 때 이 방법은 유용하다. ☺

Courting 제약조건

현재 프로젝트를 닫고 Single View Application 템플릿을 사용하여 새로운 프로젝트를 생성한다. 이름은 “Constraints” 라고 한다. 스토리보드를 사용하지 않는 아이폰 프로젝트가 될 것이다. 그러나 ARC는 사용한다.

Xcode 4.5로 새로운 프로젝트를 생성하면 오토 레이아웃을 사용한다고 가정한다. 그래서 그것을 활성화 하기 위해 어떠한 작업도 할 필요가 없다.

인터페이스 빌더를 열고 ViewController.xib를 클릭한다. 새로운 Round Rect Button을 캔버스위에 드래그 한다. 드래그하는 동안 파란색 점선의 선이 나타난다. 이런 선은 가이드라고 알려져 있다.

가이드

화면의 여백의 주위에 가이드가 있을 뿐만 아니라 가운데도 있다.

다른 가이드

이전에 인터페이스 빌더를 사용했다면, 이런 가이드를 봤을 것이다. 그것은 오브젝트를 쉽게 정렬할 수 있도록 도움이 되는 힌트이다. 그러나 오토 레이아웃이 활성화되면 가이드는 다른 목적을 가진다. 아직 그것들을 정렬을 위해 사용 하지만 새로운 제약 조건이 어디에 갈 것인지 알려준다.

파란색 가이드에 대해 왼쪽-위 코너에 버튼을 드롭한다. 이제 nib은 다음과 같을 것이다.

가이드와 버튼

두 개의 파란색 선이 버튼에 붙어 있다. 이런 T자 모양의 객체는 이 버튼에 설정된 제약 조건이다.

모든 제약조건은 인터페이스 빌더 창의 왼쪽의 Document Outline 창에 리스트 되어 있다.

Document Outline의 버튼 제약조건

현재는 두 개의 제약조건이 있다. 버튼과 메인 뷰의 왼쪽 가장자리의 사이에 Horizontal Space과 버튼과 메인 뷰의 윗쪽 가장자리 사이의 Vertical Space이다. 이러한 제약조건에 의한 표현되는 관계는 다음과 같다.

“버튼은 항상 그것의 슈퍼뷰의 왼쪽-위 모서리에 위치 한다.”

이제 버튼을 선택하고 다시 파란색 가이드를 고려하여 오른쪽-위 코너에 그것을 위치 시킨다.

위-오른쪽 코너 버튼

Horizontal Space 제약조건은 변경되었다. 더 이상 버튼의 왼쪽에 붙어 있지 않고 오른쪽에 있다.

가이드에 대한 버튼(또는 어떠한 다른 뷰)을 배치 할 때, 애플의 iOS 휴먼 인터페이스 가이드 라인 문서인 “HIG”에 정의된 표준크기의 제약조건을 얻을 수 있다. 가장자리의 주변 여백의 표준크기는 20 포인트 여백이다.

비록 가이드가 없는 곳에 버튼을 배치 할 때, 그 자리에 제약 조건을 유지 하기 위해 Horizontal 또는 Vertical Space 을 여전히 얻을 수 있다. 사용해 봐라. 다음과 같이 무언가를 얻을 때까지 왼쪽으로 조금씩 버튼을 드래그 해라.

Button larger H space

Horizontal Space 제약조건이 여전이 있지만 지금은 그것이 커졌다. Document Outline에서 더 이상 표준 공간을 가지지 않은 것을 볼 수 있다.

Larger H space document outline

버튼의 위치에 따라 얻을 수 있는 제약 조건이 달라진다.

또한 “center” 제약 조건이 있다. 버튼을 캔버스의 가운데 밑에 드래그 한다. 그러면 가이드와 함께 자석 효과로 찰싹 붙는다.

가운데 밑에 위치한 버튼

Horizontal Space 제약조건은 버튼이 항상 그것의 슈퍼뷰의 중앙 정렬을 유지하는 가로축에서 Center X 정렬 제약조건으로 대체 됨을 의미한다. 아직 뷰의 하단으로부터 버튼을 유지 하기 위해 Vertical Space 제약조건이 있다. 다시말하면 표준 여백을 사용한다.

앱을 실행하고 가로방향으로 회전시킨다. 가로방향 모드에서도 버튼은 화면의 가운데 밑에 위치한다.

가로방향에서 가운데 밑에 위치한 버튼

의도를 표현하는 방법은 다음과 같다. “이 버튼은 항상 아래쪽 중앙에 위치해야 한다”. 인터페이스 빌더에 버튼의 정확한 위치를 전달 했던 곳이 없다. 오직 뷰에 위치할 곳만 전달 했었다.

오토 레이아웃으로는 캔버스 위에 뷰를 위치 시킬 정확한 좌표 또는 크기에 대해 더 이상 신경 쓸 필요가 없다. 대신에 오토 레이아웃은 설정한 또는 인터페이스 빌더가 대신 설정한 제약조건에서 이 두 가지를 이끌어 낸다.

버튼의 Size 인스팩터에서 지금은 꽤 다른 이러한 파라다임 변화를 볼 수 있다.

Different size inspectors

오토 레이아웃을 비활성화하면 X값, Y값, 넓이 또는 높이 필드를 입력해서 선택된 뷰의 위치나 크기를 변경한다. 오토 레이아웃을 활성화하면 새로운 값을 필드에 입력 할 수 있지만 항상 원하는 효과를 얻을 수 없다. 뷰가 이동한다면 인터페이스 빌더는 새로운 값으로 새로운 제약조건을 계산한다.

예를들어 넓이 값이 100으로 변경되면 캔버스는 다음과 같이 변화 한다.

고정된 넓이의 버튼

“Center X Alignment” 제약조건이 사라지고 그 위치에는 화면의 왼쪽 가장자리에 버튼으로 붙은 “Horizontal Space”가 있다. 뿐만 아니라 그 자신의 버튼에 100 포인트의 넓이(버튼 밑의 파랑새 바)를 강제적으로 가지게 하는 새로운 제약 조건이 있다.

또한 이 새로운 “Width” 제약조건을 왼쪽의 Document Outline에서 볼 수 있다.

Document outline에서 Width 제약조건

버튼과 그것의 슈퍼뷰 사이의 다른 제약조건과 다르게 Width 제약조건은 버튼 자신에 적용된다. 버튼과 버튼 사이의 제약조건으로 생각 할 수 있다.

다시 버튼을 드래그하면 Center X Alignment 제약조건과 함께 자석효과로 달라붙는다.

팁: 싸이즈 인스펙터의 위치와 크기가 변경이 제약조건을 망칠 수 있기 때문에, 이것을 하지 않도록 권한다. 대신, 레이아웃을 변경을 원하면 제약 조건을 변경한다.

왜 전에 버튼이 Width 제약조건을 가지지 않았는지 궁금할 수 있다. 오토 레이아웃은 제약조건이 없으면서 버튼의 넓이를 어떻게 알았을까?

버튼은 스스로 어느정도 넓이를 가져야 하는지 안다. 버튼 제목의 텍스트에 코너의 주변의 패딩을 더하는 것을 바탕으로 계산을 한다. 버튼에 배경 이미지를 설정하면, 또한 계정에 그것을 적용한다.

고유 콘텐츠 크기로 알려져 있다. 모든 콘트롤이 이것을 가지지 않지만 많은 것이 가지고 있다. (다른 예는 UILabel이다) 뷰가 자신의 원하는 크기를 계산 할 수 있다면, 그것의 특정 Width 또는 Height 제약조건 설정할 필요가 없다. 나중에 이와 같은 것을 더 볼 수 있다.

나는 뚱뚱하지 않아

최적의 크기로 버튼이 반환될려면 그것을 선택하고 Editor메뉴에서 Size to Fit Content을 선택한다. 이것은 명시적 Width 제약조건을 제거하고 버튼의 고유 콘텐츠 크기를 복원한다.

손뼉도 마추쳐야 소리가 난다

오직 뷰와 그것의 슈퍼뷰 사이에서는 가이드는 나타나지 않는다. 그러나 또한 같은 레벨의 뷰 계층의 뷰 사이에서도 나타나지 않는다. 이것을 설명하기 위해서 캔버스에 새로운 둥근 사각 버튼을 드래그 한다.

버튼을 서로 충분히 떨어지게 놓으면 새로운 버튼은 자신의 제약조건을 가진다. 그러나 각 버튼을 너무 가까이 놓으면 제약조건은 상호작용하기 시작한다.

새로운 버튼을 기존에 있던 버튼 옆에 놓는다. 그러면 자석효과로 옆에 붙는다.

Snap two buttons

꽤 많은 점선 가이드라인이 여기에 있다. 그러나 인터페이스 빌더는 모든 제약조건으로 바꿀 수 없다. 기본적으로 두 버튼은 다른 방법(위쪽, 가운데 그리고 베이스라인)으로 정렬 할 수 있게 인식한다.

버튼을 드롭하고 나서 제약조건은 다음과 같다.

Two buttons

새로운 버튼은 화면의 아래에 Vertical Space를 가진다. 또한 다른 버튼과 함께 연결하는 Horizontal Space 가진다. 이 공간은 고작 8포인트 밖에 안되게 작기 때문에 T자 바를 찾기 힘들다. 그러나 거기에 있다.

Document Outline에서 Horizontal Space 제약조건을 클릭한다

Highlighted H-space between buttons

제약조건을 선택할 때 속해 있는 것은 노란색 불빛이 나게 된다. 이 특별한 제약조건은 두 개의 버튼에서 일어난다. 여기에 한 것은 이렇게 말할 수 있다.

“두 번째 버튼은 항상 첫 번째의 오른쪽에 나타나며 첫 번째 버튼이 어디에 있는지 또는 얼만큼 큰지는 문제가 안된다.”

왼쪽 버튼을 선택하고 그것의 레이블은 “A longer label”과 같이 길게 작성한다. 그것을 마치면 버튼의 크기는 새로운 텍스트에 맞춰 재조절 된다. 그리고 다른 버튼은 비켜준다. 결국 첫 번째 버튼의 오른쪽 가장자리에 붙는다. 이것이 정확하게 일어나길 바란 일이다.

긴 레이블을 가진 버튼

인터페이스 빌더가 다시 Horizontal Space의 첫 번째 버튼의 Center X Alignment를 대체 한 것을 확인할 수 있다. 매번 콘트롤의 크기나 위치를 변경 할 때, 인터페이스 빌더는 최적의 제약조건의 설정을 다시 계산한다. 대부분 올바르게 동작하지만 때때로 잘못되게 동작한다. 명백하게 버튼의 텍스트를 단지 변경하고 싶지만 여기서는 중심을 유지한다.

버튼을 다시 중심으로 드래그 한다. 이제 제약조건은 다음과 같이 된다.

연결이 끊긴 두 버튼

저것은 아마도 원하는 일이 아니다. 두 개의 버튼은 더 이상 서로에 연결되어 있지 않는다. 대신 가장 오른쪽 버튼은 이제 화면의 오른쪽 가장자리에 Horizontal Space를 가진다. 두 개의 버튼 사이의 Horizontal Space 제약조건은 더 이상 없다.

물론, 다시 자석효과로 붙여서 두 개의 버튼을 재연결 할 수 있다. 그러나 이 문제는 뷰의 주변을 드래그 하지 않음으로 피할 수 있다.

첫 번째로 Cmd-Z를 눌러 undo를 한다. 그래서 첫 번째 버튼은 더 이상 중앙 정렬이 아니다. 버튼을 선택하고 Editor메뉴에서 Container의 AlignHorizontal Center을 선택한다. 이번에는 첫 번째 버튼을 중앙으로 옮길 뿐만 아니라 다른 버튼도 함께 이동한다. 그것이 더 좋다.

이 작업의 방법에 더 좋은 느낌을 얻기 위해 여기 더 다른 작업을 한다. 작업 버튼을 선택하고 다른 하나는 위로 이동 시킨다. 그러면 수직으로 자석효과로 달라 붙는다. (그러나 두 개 버튼의 왼쪽 가장자리로 정렬을 하지 마라.)

Button on top

두 버튼을 서로 자석효과로 붙여 놓았기 때문에, 이제 두 개의 버튼 사이에는 Vertical Space가 있다. 다시 HIG에서 추천하는 8 포인트의 표준 공간을 가진다.

한글번역파트는 글자수 초과문제로 각파트를 2개의 파트로 나눈다. 계속해서 이 튜토리얼의 파트 1-2를 읽어라.

반응형
Posted by 컴스터
,