ios) Margins & Guides + (Adaptive Layout)

5 minute read

Layout Margins & Guides

Layout Margin

스크린샷 2021-02-19 오후 4 03 20

Layout Margin은 뷰에 표시되는 내용과 뷰의 Bound 사이의 간격을 말한다.

ios8이 출시하면서 도입이 되었다.

UIView 클래스에 속성으로 선언되어있고, Top, Bottom, Left, Right의 마진을 개별적으로 지정한다.

스크린샷 2021-02-19 오후 6 10 24

ios11버젼이 나오면서 safeArea가 도입되었고, 이전 버젼과의 다른 방식으로 동작하며

ios11에서는 safeArea나 다른 속성의 영향을 받을 수 있기 때문에 차이점을 잘 비교해야한다.

현재 오렌지뷰는 루트뷰와의 Top, Bottom, Left, Right 제약이 걸려있다.

스크린샷 2021-02-19 오후 6 37 32

루트뷰를 선택후 사이즈 인스펙터를 보면 Layout Margins에는 기본값이 Default로 되어있다.

스크린샷 2021-02-19 오후 6 38 08

Layout Margins을 Fixed로 바꾸고 네가지 방향에 100씩 지정하면 오렌지뷰가

루트뷰로부터 각각 100의 margin을 가지게 되는 것을 확인할 수 있다.

스크린샷 2021-02-19 오후 6 38 37

ios11부터 루트뷰의 Layout Margin이 Safe Area를 고려한다.

네비게이션 바 or 탭 바가 추가되어있다면 각각에 겹치지 않는 최소 Margin이 지정된다.

다시한번 루트 뷰의 사이즈 인스펙터를 보면 **Safe Area Relative Margins가

기본적으로 체크되어있다. Safe Area를 고려하겠다!! 라는 속성인데 체크를 해제하게되면

Safe Area를 무시하는 값으로 Margin이 지정된다.

스크린샷 2021-02-19 오후 6 44 09

ios11부터 바뀐 또 하나의 변경사항은 LayoutMargins 속성대신

Directional Margins 속성을 사용한다. 이 속성은 언어의 방향을 고려하기 위해

Left, Right 대신에 Leading, Trailing을 사용한다.

속성 또한 UIEdgeInsets이 아닌 NSDirectionalEdgeInsets이다.

Layout Margins에서 Language Directional을 선택하게 되면

Leading과 Trailing으로 변경되고 값은 그대로 남아있다.

스크린샷 2021-02-19 오후 9 14 59

Directional은 ios11 버전 이상부터 사용가능하기에 그 이하 버전으로 앱을 배포할 때에는

호환성 문제에 대해 주의해야한다.

ios11 버전에서는 Directional Layout Margins를 사용하고,

이전 버전에서는 Layout Margins을 사용하게 하는 것이 중요하다.

Fixed와 Language Directional중 하나만 선택가능하기에 코드를 통해 처리해야한다.

if #available(ios 11.0, *) {
  view.directionalLayoutMargins = NSDirectionalEdgeInsets(top:leading:bottom:trailing:)
} else {
  view.layoutMargins = UIEdgeInsets(top:left:bottom:right:)
}

Margin을 기준으로 배치하는 것과 Bound를 기준으로 배치하는 것은 큰 차이를 가지고 있다.

Margin은 safe area 또는 super view의 영향을 받을 수 있다.

제약을 추가할 수 있는 핀 버튼을 클릭하면 Constrain to margins를 체크할수 있는 부분이 있다.

체크를 하게되면 뷰의 margin이 safe area를 고려하여 설정이 되고,

체크를 해제하고 제약을 주게되면 margin을 무시하고 Bound를 기준으로 배치된다.

Bound를 기준으로 배치할 때에는 네비게이션 바 또는 탭바같은 시스템 뷰와 겹칠 수 있다.

스크린샷 2021-02-19 오후 9 44 29

또한 위에서 보았던 루트 뷰의 사이즈 인스펙터에서 Directional Layout Margins를 선택 후

값을 변경해도 Bound를 기준으로 배치된 뷰는 영향을 받지 않는다.

VC에서 Margins를 변경할 때 주의할 점

스크린샷 2021-02-19 오후 10 13 36

오렌지뷰는 루트뷰를 기준으로 top,leading,bottom,trailing은 모두 0으로 설정되어있고,

루트뷰의 Layout Margins를 모두 5로 설정했다.

스크린샷 2021-02-19 오후 10 14 51

하지만 오렌지뷰의 제약을 다시 보면 Top과 Bottom은 5로 되었지만

Leading과 Trailing은 5보다 큰 20으로 되어있는 것을 볼 수 있다.

이 값은 루트뷰의 minimum margins이다. Minimum margins보다 작은 값을 설정하면

설정된 margins 대신 minimum margins이 설정된다.

그 이유는 루트뷰의 내용이 적절히 표시되도록 보장하기 위해서이다.

minimum margins 대신 직접 입력한 margins를 사용하려면

VC가 minimum margins을 사용하지 않도록 설정해야 한다.

스크린샷 2021-02-19 오후 10 21 23

ios11부터 지원하기 때문에 배포상태에 따라 분기를 해주어야 한다.


Layout Guides

ios11 이후 VC는 풀 스크린 방식을 사용한다. 시스템 뷰가 VC위에 표시되면서

뷰와 시스템 뷰가 겹치지 않게 하는 것이 중요해졌다.

레이아웃 가이드는 이러한 문제를 해결하기 위해 도입되었다.

Safe Layout Guides를 현재는 사용중이다.

파일 인스펙터를 보면 기본으로 Use Safe Area Layout Guides가 체크되어있다.

스크린샷 2021-02-20 오전 1 19 09

Safe Layout Guides와 이 전 Layout Guides는 두가지 차이점이 있다.

첫번째 차이점은 Layout Guides는 VC의 속성이었지만 Safe Layout Guides는 View의 속성이다.

도큐먼트 아웃라인을 보면 Safe Area가 자동으로 추가되어 있다!

스크린샷 2021-02-20 오전 1 22 10

Use Safe Area Layout Guides의 체크에 따라 달라지는 것을 볼 수 있다.

스크린샷 2021-02-20 오전 1 24 37

스크린샷 2021-02-20 오전 1 24 43

두번째 차이점은 가이드의 영역이다. Safe Area는 Top과 Bottom으로 구분되지않은 하나의 영역이다.

Safe Area를 사용하는 경우에는 이전 버전과의 호완성을 유지한다.

ios11을 기준으로 이전 버전에는 Layout Guides로 자동으로 변환된다.

인터페이스 빌더에서는 오류없이 실행이 되지만 코드로 제약을 추가할 때에는 버전에 적합한 가이드를 사용해야 한다.

스크린샷 2021-02-20 오전 1 36 33

Layout Margins과 Safe Area 변경 될 때 활용할 수 있는 메서드

layoutMarginsDidChange() // 뷰에 레이아웃 margins이 변경 될 때마다 호출

safeAreaInsetsDidChange() // SafeArea의 크기가 변경 될 때마다 호출

class EventsViewController: UIViewController {
  // 루트 뷰의 margins이 변경 될 때마다 호출
  override func viewLayoutMarginsDidChange(){
    super.viewLayoutMarginsDidChange()
  }
  // 루트 뷰의 Safe Area Inset이 변경 될 때마다 호출
  override func viewSafeAreaInsetsDidChange() {
    super.viewSafeAreaInsetsDidChange
  }

}

Adaptive Layout

실행환경에 따라사 가장 적합한 방식으로 동작하는 앱의 기술을 구현학고,

모든 디바이스와 실행 환경에서 동작할 수 있는 하나의 UI를 개발하는 방법이

Adaptive Layout이다.

ios8 버전 이전에는 스토리보드에서 아이폰과 아이패드의 개발이 따로 분리되어있었지만

Adaptive Layout에서는 디바이스의 독립적인 Universal Storyboard를 사용한다.

Universal Storyboard는 다음의 중요한 세가지와 결합해서 모든 디바이스와

실행환경에 적용이 가능한 단일 Layout을 구현한다.

  • Saze Class - 뷰를 배치할 수 있는 공간의 크기를 구분
  • Trait Collection - 세부적인 실행환경을 구분
  • Auto Layout

Adaptive Layout은 뷰의 계층과 화면의 전환에도 영향을 준다.

예를들어 아이폰 같은 작은 사이즈에서는 Push & Pop으로 화면 전환을 구현하고,

화면이 큰 아이패드의 경우 목록과 내용이 함께 표시된다.

Size Class

Size Class는 인터페이스의 크기를 두개로 표현한다.

Class는 계층이나 종류를 의미하고(swift 문법의 class X)한다.

  • Regular class - 너비나 높이가 비교적 크다는 것을 의미
  • Compact class - 너비나 높이가 비교적 작다는 것을 의미
  • Any class - 어느 한 방향의 클래스를 지정하지 않는다는 의미

Horizontal 또는 Vertical 사이즈 클래스를 통해서 너비와 높이에 해당하는 클래스를 개별적으로 지정한다.

더 상세한 디바이스의 Size Class는 H.I.G에서 확인할 수 있다.

스크린샷 2021-02-20 오후 4 34 03

Trait Collection

Size Class 보다 더 상세학게 실행환경을 구분할 때 사용하며

ios 앱이 실행하는 환경에 대한 다양한 정보를 담고있다.

UITraitCollection
UITraitEnvironment

인터페이스 빌더 아래쪽을 보면 View as가 있는데 디바이스와 Size Class가 표시된다.

w는 Horizontal Size Class이고, h는 vertical Size Class를 뜻한다.

C는 Compact, R은 Regular을 뜻한다.

스크린샷 2021-02-20 오후 5 18 14

파일 인스펙터를 보면 Use Trait Variations가 기본적으로 체크되어있다.

체크가 활성화가 되어있어야 Adaptive Layout을 구현할 수 있다.

그래야 하나의 Universal Storyboard에 Size Class로 분기된 정보와

Trait로 분기된 정보를 함께 저장할 수 있다.

스크린샷 2021-02-20 오후 5 24 07


Adaptive Layout 실습해보기

오렌지 뷰와 텍스트 뷰는 각각의 제약을 가지고 있다.

현재 추가된 제약들은 어떤 Size Class에서도 종속되지 않고, 어떠한 디방이스에서도

항상 동일한 레이아웃으로 지정된다.

스크린샷 2021-02-20 오후 7 49 20

디바이스를 LandScape 모드로 설정하면 아래와 같은 뷰가 나오는데

두 뷰를 수평으로 두기 위한 작업을 하기위해 오른 쪽 하단에 vary for traits을 선택한다.

스크린샷 2021-02-20 오후 7 53 47

수평을 맞추기 위해서는 vertical size만 고려하기에 height만 체크하면

아래 사진과 같이 파란색으로 강조된다. 좌측을 보면 variation이 compact 항목인

디바이스만 표시되고 이 뜻은 아이폰이 Landscape일 때만 적용한다는 뜻이다.

아이패드는 수직,수평이 모두 Regular이기 때문이다.

스크린샷 2021-02-20 오후 7 59 20

인터페이스 빌더의 빈 공간을 클릭하면 Done Varying로 바뀌고 작업을 시작할 수 있다.

이 같이 파란색인 상태에서 인터페이스 빌더에서 수행한 편집 내용은 모두 현재

variation에 저장된다. 작업이 끝난 후에는 Done Varying을 꼭 클릭하여 완료해야한다.

스크린샷 2021-02-20 오후 8 04 23

variation상타에서 제약을 바꾸기 위해 기존에 있던 제약을 삭제하게 되면

기존의 제약과 다르게 반투명 색깔로 비활성화가 된다.

스크린샷 2021-02-20 오후 8 07 13

기존에 수정해 줘양할 제약들을 비활성화 한 상태에서 새로운 제약을 주고 Done버튼을 클릭하면

각각의 모드에서 서로다른 UI를 줄 수 있다.

스크린샷 2021-02-20 오후 8 12 26 스크린샷 2021-02-20 오후 8 12 30

오렌지 뷰의 width 제약을 선택하고 인스펙터를 보면 hC - Installed가 체크되어 있다.

‘vertical size가 compact 일때 적용되는 항목’이라는 뜻이다.

위에 체크되어있지 않은 Installed는 그 이외의 나머지 항목을 뜻한다.

다른 제약들도 인스펙터에서 어떤 항목이 체크되어 있는지 확인할 수 있다.

왼쪽에 + 또는 x를 통해서 variation을 추가하거나 삭제할 수도 있다.

스크린샷 2021-02-20 오후 8 15 44

기존에 있던 variation을 삭제하고 +를 눌러보면 variation을 설정할 수 있는 팝업이 표시된다.

스크린샷 2021-02-20 오후 8 20 05

vertical size만 고려하면 되기에 height만 compact 모드로 설정하고

나머지는 Any로 설정 후 Add variation을 하게되면

처음 실습했던 파란색 화면이 뜨고 제약을 비활성화하고,, 이런 것 없이 간단히 추가할 수 있다.

스크린샷 2021-02-20 오후 8 21 20


variation을 추가하거나 편집하는 기술은 adaptive layout에서 가장 중요한 기술이다.

실습에서 첫번째로 했던 방법은 편집내용이 광범위한 경우에 편리하다.

두번째로 인스펙터에서 variation을 추가하는 방법은 개별 항목별로 추가하거나 삭제할 때 편리하다.

Comments