 Apple Lover Developer & Artist

영속적인 디자인에 현대의 공감을 채워넣는 공방입니다

 Apple/iOS Dev Challenges

[Challenge] 🛠️ iOS 앱 설계 퓨전 레시피 9부 - View 디자인

singularis7 2023. 3. 4. 17:57
반응형

Overview

스토리보드에서 정의한 앱의 흐름에서 View 디자인을 구체화시켜본다.

Pattern

프로젝트에서 사용할 View의 정의 패턴을 소개한다.

TableView Cell

UIKit이 제공하는 표준 스타일의 셀을 사용한다. Basic, Subtitle, Right Detail, Left Detail 총 4가지 레이아웃을 제공한다. 표준 레이아웃의 프로퍼티를 커스텀하여 빠르게 TableView Cell을 만들 수 있다.

TableView Cell의 생성하기 위해 Identifier를 부여한다. Identifier는 성능상의 이유로 TableView가 재사용 메커니즘을 활용해 Cell을 생성할 수 있도록 돕는다.

Layout

기본적으로 오토 레이아웃을 활용한다. View를 정밀히 조정해야 할 때 오토 레이아웃의 제약 조건을 사용한다. 그 외에는 오토 레이아웃 규칙을 활용한 고수준의 레이아웃 접근을 도와주는 StackView를 활용해 View를 배치한다.

Implement

앞서 소개한 View 생성 규칙을 활용해 본다. 먼저 카테고리, 음식메뉴, 주문서의 아이템을 보여줄 TableView Cell을 만들어 볼 것이다.

TableView Cell

Categories Table View Cell

카테고리 개별 정보는 Title을 의미하는 String 데이터 하나로 구성돼있다. 하나의 Title을 보여주기 위해 Table View Cell의 표준 스타일 중 Basic을 선택했다.

TableView Cell의 Accessory에 Disclosure Indicator를 삽입해 줌으로써 사용자에게 아이템의 세부 정보를 보여주기 전에 더 탐색할 Navigation 계층이 있다는 점을 안내해 주었다. (참조: HIG -Lists and tables "Platform considerations")

셀의 식별자는 Category로 지정해 주었다. 세부적인 구현은 다음과 같다.

img

Menu Table View Cell

메뉴 개별 정보는 Title을 의미하는 이름 String 데이터와 세부 정보인 미화 가격 Double 데이터 그리고 음식 사진을 보여줄 이미지 데이터로 구성된다.

음식 메뉴의 이름에 더해 가격까지 보여줘야 하기 때문에 Cell Style로 Right Detail을 사용했다.

개별 음식 메뉴의 세부 정보를 보여주는 화면을 더 탐색할 수 있다는 정보를 사용자에게 안내하고자 Disclosure Indicator를 삽입하였다.

표준 TableView Cell 스타일이 이미지 정보를 optional 하게 보여줄 수 있도록 구성되었다는 점에서 착안하여 기본 이미지를 상징하는 SFSymbole photo.on.rectangle을 설정했다.

셀의 식별자는 MenuItem으로 지정해 주었다. 세부적인 구현은 다음과 같다.

img

Order Table View Cell

주문서의 아이템은 모두 음식 메뉴 아이템이다. 셀에서 보여줄 데이터는 MenuItem TableView Cell과 동일하다.

Cell의 디자인은 MenuItem TableView Cell의 방식대로 설정해 준 후 식별자 Order를 지정해 줬다. 세부 구현은 다음과 같다.

img

Plain View Layout

오토 레이아웃 규칙을 활용해 사용자 정의 화면을 구성한다. (참조: 오토 레이아웃 가이드)

MenuItem View

메뉴 아이템 세부정보를 보여줄 화면을 구성한다. 음식 메뉴는 이름, 가격, 요약글, 사진 세부 정보를 갖고 있다.

먼저 문자열 정보를 보여줄 3개의 레이블과 1개의 이미지 뷰를 ViewController 위에 얹어 준다. 각 오브젝트가 담당하는 역할에 기반해 기본값 텍스트나 이미지를 설정해 준다.

인터페이스 빌더의 추론 기능을 활용하기 위해 이름과 가격 레이블을 일직선 상에 위치시킨다. Xcode의 Embed In StackView를 활용해 horizontal stack view로 묶어준다. 이어서 이미지 뷰와 horizontal stack view 그리고 디테일 레이블을 vertical stackview로 묶어준다.

오토 레이아웃 규칙을 활용해 vertical stackview를 화면에 배치해 보겠다. vertical stackview의 top, leading, trailing을 safe area guide와 15포인트만큼 떨어지도록 제약을 건다. horizontal과 vertical stack view 모두 Alignment와 Distribution은 Fill 그리고 Spacing은 8로 설정해 준다. 여기까지 오면 다음과 같다.

img

여기까지 설정하면 몇 가지 문제가 눈에 띈다. 첫 번째로 이미지 뷰의 크기가 너무 작다. 두 번째는 앞서 설정한 horizontal stackview에서 priority 오류가 발생한다.

첫 번째부터 해결해 보자. 아이디어는 이미지 뷰의 크기를 키워주는 것이다. 이번에 사용해 볼 방식은 부모 뷰의 높이에 따라 이미지 뷰의 높이가 조정될 수 있도록 설정해 준다. 이미지 뷰와 ViewController의 뷰와 높이 제약 조건을 걸어준다. 이미지 뷰의 높이를 부모 뷰 높이의 0.25배로 설정해준다. 화면 사이즈를 바꿔가며 이미지의 높이가 잘 변경되는지 확인해 보면 문제는 해결된다.

다음은 priority 충돌 문제이다. 원인은 vertical과 horizontal stack view 모두 Alignment와 Distribution을 fill로 설정한 것과 관련 있다.

Stackview는 기본적으로 각 view의 intrinsic size를 기반으로 배치한다. intrinsic size는 view의 콘텐츠에 기반하여 결정된다. 따라서 콘텐츠에 따라 특정 뷰가 스택 뷰 내부에서 차지하는 공간이 달라질 수 있다. StackView 내부에 배치된 뷰들 중 누구를 조정할지는 가중치 개념을 사용해 결정한다.

Stack View에선 content hugging priority와 content compression priority를 조정할 수 있다. 전자는 뷰를 안쪽 방향으로 당겨서 콘텐츠 intrinsic size에 맞춰지도록 조정해 준다. 후자는 뷰를 밖으로 밀어서 콘텐츠가 잘리지 않도록 조정할 수 있다.

다시 문제를 해석해 보면 배치와 배분이 fill로 설정된 스택뷰의 내부 공간을 채우기 위해 배치된 view의 크기를 조정하려고 보니 모두 동일한 가중치를 갖고 있어서 조정 대상을 결정하지 못한 것이다.

문제를 해결하기 위해 이름 레이블 보다 가격 레이블의 content hugging priority를 낮춰주어 가격 레이블의 콘텐츠를 감싸도록 View를 안쪽으로 당겨주고 스택 뷰의 나머지 빈 공간을 이름 레이블이 점유하도록 코딩해 주었다. 구현은 다음과 같다.

img

사용자가 보고 있는 세부 상품을 주문서에 담을 수 있도록 버튼을 올려주었다. SafeArea의 leading, trailing, bottom에 패딩을 15 포인트 주었다. 버튼의 크기를 Large로 설정해 주어 버튼을 누르기 쉽도록 구현해 보았다. 최종적으론 다음과 같다.

img

Order Confirmation View

앱의 주문서 탭에서 주문 확인 버튼을 누르면 음식 준비 완료 전까지 남은 시간을 계산해 주는 화면이 나온다.

Progressive Bar을 통해 동적으로 계산된 잔여 시간을 보여주고 사용자가 원하면 모달 창을 나갈 수 있도록 버튼을 구현한다. 구현 원리는 앞서 소개한 방법과 동일하며 필자는 다음과 같이 배치해 보았다.

img

마무리

인터페이스 빌더에서 표준 스타일의 TableView Cell과 오토 레이아웃을 활용해 View를 정의해 보았다 🤩

View에 데이터를 띄우기 위해 앞선 데이터 바인딩 포스팅에서 소개하는 기본 패턴을 활용해 볼 수 있다.

다음 시간에는 UI 이미지 로딩 기능을 구현해 보겠다!

반응형