본문 바로가기

공부/iOS

iOS - StackView(2) 애플문서 샘플예제(SimpleStackView, NestedStackViews)

안녕하세요. brody입니다.

 

오늘은 저번 시간에 이어 StackView 2번째 글이에요!

 

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html

애플 공식 문서에 있는 예제를 테스트하면서 StackView를 조금 더 알아볼게요.

 

참고로 위의 공식 문서에서 제공하는 샘플 코드는 실행이 안됩니다. 실행이 되게 Swift 버전 컨버팅  해놓은 소스는 아래에 깃헙에 있어요.

https://github.com/brody424/iOS_StackView_Exam_Cookbook_Swift5

그리고 화면이 엄청 많은데 앞에 3개 화면만 StackView와 관련이 있어요.( DynamicStackView, NestedStackViews, SimpleStackView )

 

 

그럼 공식문서를 번역하면서 ~ StackView 2번째 포스팅 시작할게요!

 


Stack Views

이 예제는 StackView를 사용하여 증가하는 복잡성의 레이아웃을 만드는 방법을 보여줍니다. 

StackView는 사용자 UI를 빠르고 쉽게 설계할 수 있는 강력한 도구입니다.

여러 가지 속성을 사용하여 배열된 뷰(arranged views)를 배치하는 방법을 높은 수준으로 제어할 수 있습니다.

추가로 커스텀 제약조건(custom constraints)를 사용하여 이러한 설정을 늘릴 수 있지만, 이렇게 하면 레이아웃의 복잡성이 증가합니다.

아래의 Auto Layout Cook 프로젝트를 참고하세요.

 

 


Simple Stack View

아래는 단일 수직 StackView를 사용하여 Label, imageview, button을 가로 정렬로 배치 한 예제입니다.

(참고 프로젝트에 SimpleStackView.storyboard 파일을 참고하세요.)

 

 

 

Views and Contraints

인터페이스 빌드에서 수직 스택 뷰를 드래그하여 놓고 Flowers label, Image view와 Edit Button을 추가합니다.

 

그런 다음 아래와 같이 제약조건을 설정합니다.

 

 

 

Attributes

StackView의 Attributes inspector에 아래와 같이 attributes를 설정합니다.

 

 

그 후 imageview에 attribute를 아래와 같이 설정합니다.

 



마지막으로 Size inspector에서 imageview content-hugging과 compression-resistance(CHCR)에 우선순위를 설정합니다.

 

Discussion

 

StackView를 반드시 super view에 고정해야 합니다. 하지만 그렇지 않다면 StackView가 다른 명시적인 제약 조건 없이 전체 레이아웃을 관리합니다.

이 예제에서는 StackView가 superview를 최소의 margin으로 채웠습니다.

StackView 내에 배열된 뷰(arranged views)는 StackView의 bounds와 맞게 사이즈가 조정되었습니다.

수평(horizontally)으로는 각각의 뷰는 StackView의 너비(width)와 맞게 늘어납니다.

수직(verically)으로는 뷰들의 CHCR 우선순위에 따라 늘어났습니다.

ImageView는 항상 줄어들거나 커지면서 가능한 공간을 채웁니다.

따라서, 수직으로는 content-hugging과 compression-resistance 우선순위는 Label 및 Button의 기본 우선순위보다 낮아야 합니다.

마지막으로 imageview의 mode를 aspect Fit으로 변경합니다.

이 설정을 사용하면 강제적으로 이미지가 imageview의 가로 세로 비율을 유지하면서 한계에 맞게 크기가 조절됩니다.

이렇게 하면 StackView가 이미지를 왜곡하지 않고 이미지 뷰의 크기를 임의로 조정할 수 있습니다.

뷰를 고정하여 해당 super view를 채우는 방법에 대한 자세한 내용은 Attributes와 Adaptive Single View 예제를 참고하세요.

 

 


Nested Stack Views

이 예제는 중첩된 Stack View의 여러 레이어로 작성된 복잡한 레이아웃을 보여줍니다.
하지만 이 예제에서 Stack View는 원하는 동작만 만들 수 없습니다.
대신 레이아웃을 더욱 세분화하려면 추가 제약조건이 필요합니다.

 

 

뷰 계층 구조를 작성한 후 다음 섹션인 Views and Constraints 섹션에서 표시된 제약조건(Constraints)을 추가합니다.

 

Views and Constraints

중첩된 스택 뷰로 작업할 때는 안쪽부터 바깥쪽으로 작업하는 것이 가장 쉽습니다.

먼저 인터페이스 빌더를 사용하여 name row를 배치하는 것부터 시작합니다.

label과 text field를 올바른 상대 위치 (label 은 왼쪽 textfield는 오른쪽)에 배치하고 둘 다 선택한 다음 
상단에 Editor > Embed In > Stack VIew를 클릭합니다.

이렇게 하면 행에 대한 horizontal Stack View가 만들어집니다.

그런 다음 이 행을 수평으로 배치하고 선택한 다음 Editor > Embed In > Stack View 메뉴 항목을 다시 클릭합니다. 

이렇게 하면 행의 수평 스택이 만들어집니다. 그림과 같이 인터페이스를 계속 빌드합니다.

 

(이게 뭔 소리죠..? 번역한 게 맞나...?? 아무리 봐도 이해가 안돼서 아래의 보라색 부분은 예제를 보고 제가 작성한 글입니다.)

 

 

아래의 그림은 위에 StackView에서 Stack View만 분리한 모습이에요.

스택 뷰 안쪽부터 바깥쪽으로 작업하는 것이 좋았다고 했으니 스택 뷰로 만들 안쪽부터 확인해보죠.

첫번째로는제일 안쪽에 있는 StackView는 파란색 바탕의 아래 그림이죠.

위의 StackView를 만드려면 인터페이스 빌더에서 Label과 TextField를 만든 후 두개를 드래그하여 Editor > Embed In > Stack View 를 클릭하면 됩니다. 

 

그러면 horizontal Stack View가 만들어 집니다.

 

두번째로는 위에 만든 StackView가 3개 수직적으로 있는 뷰인데, 아래 그림이에요.

파란색 Stack View를 3개 만든 후 Stack View를 드래그 하여 위에와 같이 Editor > Embed In > Stack View를 클릭하면 됩니다.

 

그러면 vertical Stack View가 만들어 집니다.

 

마지막으로 이미지뷰를 만들고 두번째 단계에서 만든 StackView를 수평으로 놓고 Editor > Embed In > Stack View 를 클릭하면 아래와 같이 완성됩니다.

 

후.. 여기까지가 제가 실습하면서 위의 Nested Stack View 예제 만드는법이였습니다. 그럼 다시 문서로 돌아갈게요~

 

Attributes

각 스택은 고유한 attributes 집합이 있습니다.

 

스택의 내용물을 표시하는 방법을 정의합니다.

 

Attribute inspector에 다음 attributes를 설정합니다.

 

또한 TextView에 옅은 회색 배경색을 지정합니다.

 

이렇게 하면 방향이 변경 될 때 Text view의 크기를 쉽게 확인 할 수 있습니다.

 

 

마지막으로 CHCR 우선 순위는 사용 가능한 공간을 채우기 위해 어떤 뷰를 확장해야 하는지 정의합니다.

 

Size inspector에서 다음 CHCR 우선 순위를 설정합니다.

 

 

Discussion

이 예제에서는 Stack View가 함께 작동하여 대부분의 레이아웃을 관리합니다.

 

그러나 원하는 모든 행동을 스스로 만들 수 없습니다.

 

ImageView

예를들어 ImageView의 크기가 조정될 때 이미지의 가로 세로 비율을 유지해야 합니다.

 

하지만 Simple Stack View에서 사용되는 기술은 여기서 작동하지 않습니다.

 

레이아웃은 이미지의 trraling 과 bottom 가장자리에 모두 가깝게 맞아야 하며, Aspect Fit 모드를 사용하면 해당 치수 중 하나에 추가 공백을 추가 할 수 있습니다.

 

다행히 이 예에서는 이미지의 가로 세로 비율이 항상 정사각형이기 때문에 이미지가 ImageView의 한도를 완전히 채우도록 하고 ImageView를 1:1 가로 세로 비율로 제한할 수 있습니다.

 

TextField(이름,중간이름,성 을 입력하는 부분)

또한 모든 TextField의 width는 같아야 합니다.

 

불행하게도 3개의 TextField는 모두 개별 Stack View에 있으므로 Stack에서 이 TextField를 관리할 수 엇습니다.

 

대신에 동일한 너비 제약 조건을 명시적으로 추가해야 합니다.(확인해보니 Constraint를 Equal Width 로 묶어두었네요)

 

Simple Stack View와 마찬가지로 일부 CHCR 우선 순위도 수정해야 합니다.

 

super class의 boundes가 변경됨에 따라 View가 축소 및 확장되는 방식을 정의합니다. 

 

CHCR

수직적으로 TextView(회색 배경) 를 확장하여 상단 Stack 과 버튼 Stack 사이의 공간을 채울 수 있습니다.

따라서 TextView 의 수직 content-hugging은 다른 content-hugging보다 낮아야 합니다. (그래야만 TextView가 가변적으로 늘어나겠죠?)

 

수평적으로는 Label은 고유한 내용 크기로 표시되어야 하며 TextField는 추가 공간을 채우도록 크기를 조정해야 합니다.

 

기본 CHCR 우선순위는 Label에 대해 잘 작동합니다. 

 

Interface builder는 이미 content-hugging을 251로 설정하여 TextField 보다 높게 설정했지만,

TextField의  horizontal content hugging 과 horizontal compression resistance를 모두 낮춰야 합니다.

 

ImageView느 name rows를 포함한 StackView와 높이가 같도록 축소되어야 합니다.

 

그러나 StackView는 그 내용을 느슨하게 감싸기만 합니다.

 

즉 ImageView의 vertical compression resistance는 매우 낮기 때문에 StackView를 확장하는 대신 ImageView를 축소시킵니다.

 

또한 ImageView의 가로 세로 비율을 제약 조건으로 추가하여 수직 및 수평 제약 조건이 상호 작용할 수 있기 때문에 레이아웃으 복잡해집니다.

 

즉 TextField의 horizontal content huggin또한 매우 낮아야 합니다. 그렇지 않으면 ImageView가 축소되지 않습니다.

 

두 경우 모두 우선순위를 48 이하로 설정했습니다.

 

 


 

너무 글이 길어져서 마지막 예제인 Dynamic Stack View는 다음 포스팅에서 알아보도록 할게요 ㅠ...

 

 글만 보면 이해가 잘 안되는 부분이 있으니 꼭 프로젝트를 직접 들어가서 테스트해보시고 확인하는걸 추천드려요.

 

StackView가 끝나는 대로 content-hugging 과 compression-resistance(CHCR)에 대해서도 정리 해볼게요.

 

그럼 ㅅㄱㄹ!